2022.3.26 NOI Online記
阿新 • • 發佈:2022-03-26
提高組
T1 丹釣戰
剛開始看到這個題,非常自覺的打了暴力,預計得分 50pts ,後來寫了個主席樹,結果 xixike 學長說主席樹可能會被卡,寫離線樹狀陣列好一些。。。。
但願不會被卡。。。。
#include <algorithm> #include <bitset> #include <string> #include <vector> #include <iosfwd> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> #include <queue> #include <set> #define ll long long using namespace std; const int maxn = 500000+5; inline ll read() { ll x=0; bool f=1; char c=getchar(); while(c>57||c<48){ if(c=='-') f=0; c=getchar(); } while(c<=57&&c>=48) x=(x<<1)+(x<<3)+c-48,c=getchar(); return f?x:(~x)+1; } struct node { int l,r,sum; }tree[maxn*40]; struct NODE { int a,b,i; }sz[maxn],sta[maxn]; int n,m,k,t,cnt,tail,num[maxn],b[maxn],rt[maxn]; struct point { int id,w; }a[maxn]; bool operator < (point s1,point s2) { if(s1.w!=s2.w) return s1.w<s2.w; else return s1.id<s2.id; } void update(int root) { tree[root].sum=tree[tree[root].l].sum+tree[tree[root].r].sum; } void build_0(int &root,int l,int r) { root=++cnt; tree[root].l=l; tree[root].r=r; tree[root].sum=0; if(l==r) return; int mid=(l+r)/2; build_0(tree[root].l,l,mid); build_0(tree[root].r,mid+1,r); update(root); } void build(int pre,int &root,int l,int r,int index) { root=++cnt; tree[root]=tree[pre]; if(l==r) { tree[root].sum++; return; } int mid=(l+r)/2; if(index<=mid) { build(tree[pre].l,tree[root].l,l,mid,index); } else { build(tree[pre].r,tree[root].r,mid+1,r,index); } update(root); } int binary(int l,int r,int k) { while(l<=r) { int mid=(l+r)/2; if(a[mid].w>k) { r=mid-1; } else { l=mid+1; } } return r; } int ask(int root1,int root2,int L,int R,int l,int r) { if(L>R) { return 0; } if(l>=L&&r<=R) { return tree[root2].sum-tree[root1].sum; } int mid=(l+r)/2,ans=0; if(mid>=L) { ans+=ask(tree[root1].l,tree[root2].l,L,R,l,mid); } if(mid<R) { ans+=ask(tree[root1].r,tree[root2].r,L,R,mid+1,r); } return ans; } int main() { freopen("stack.in", "r", stdin); freopen("stack.out", "w", stdout); n=read(); m=read();cnt=0; for(int i=1;i<=n;i++) { sz[i].a=read(); } for(int i=1;i<=n;i++) { sz[i].b=read(); } for(int i=1;i<=n;i++) { while(tail&&(sta[tail].a==sz[i].a||sz[i].b>=sta[tail].b)) { tail-=1; } sta[++tail].a=sz[i].a;sta[tail].b=sz[i].b;sta[tail].i=i; if(tail==1) { num[i]=1; } else { num[i]=sta[tail-1].i+1; } a[i].id=i; a[i].w=num[i]; } sort(a+1,a+n+1); for(int i=1;i<=n;i++) { b[a[i].id]=i; } build_0(rt[0],1,n); for(int i=1; i<=n; i++) { build(rt[i-1],rt[i],1,n,b[i]); } int l,r,k; while(m--) { l=read(); r=read(); k=num[l]; int index=binary(1,n,k); printf("%d\n",ask(rt[l-1],rt[r],1,index,1,n)); } return 0; }
T2 討論
賽時就打了個暴力,是真沒時間了,,,,第一道題我硬生生寫了 3 小時。。。。
#include <bits/stdc++.h> using namespace std; const long long A = 1e2 + 7; const long long B = 1e3 + 7; const long long C = 1e4 + 7; const long long D = 1e5 + 7; const long long E = 1e6 + 7; const long long INF = 0x3f3f3f3f; const long long mod = 1e9 + 7; inline long long read() { long long x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } long long t, n; set<long long> a[C]; bool check(long long x, long long y) { bool f1 = false, f2 = false, f3 = false; for(long long i = 0; i <= n; i++) { if(a[x].find(i) != a[x].end() && a[y].find(i) != a[y].end()) f1 = 1; else if(a[x].find(i) != a[x].end() && a[y].find(i) == a[y].end()) f2 = 1; else if(a[x].find(i) == a[x].end() && a[y].find(i) != a[y].end()) f3 = 1; } if(f1 && f2 && f3) return 1; return 0; } int main() { freopen("discuss.in","r",stdin); freopen("discuss.out","w",stdout); t = read(); while(t--) { long long res = 0, ans1 = 0, ans2 = 0; n = read(); for(long long i = 1; i <= n; i++) { long long x = read(); for(long long j = 1; j <= x; j++) a[i].insert(read()); } for(long long i = 1; i <= n; i++) { for(long long j = i +1; j <= n; j++) { if(check(i, j)) ans1 = i, ans2 = j, res ++; } } if(!res) puts("NO"); else printf("YES\n%d %d\n", ans1, ans2); for(long long i = 1; i <= n; i++) a[i].clear(); } return 0; }
T3 如何正確地排序
同上,隨手暴力一波就下了。。。
#include <ctime> #include <iostream> #include <istream> #include <ostream> using namespace std; const long long A = 1e2 + 7; const long long B = 1e3 + 7; const long long C = 1e4 + 7; const long long D = 2e5 + 7; const long long E = 1e6 + 7; const long long INF = 0x3f3f3f3f; const long long mod = 1e9 + 7; inline long long read(){ long long x = 0, f = 1; char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } long long m, n; long long a[D][10]; int main(){ freopen("sort.in","r",stdin); freopen("sort.out","w",stdout); m=read(),n=read(); for(long long i = 1; i <= m; i++) { for(long long j = 1; j <= n; j++) { a[i][j] = read(); } } long long ans = 0; for(long long i = 1; i <= n; i++) { for(long long j = 1; j <= n; j++) { long long mn = INF, mx = 0; for(long long k = 1; k <= m; k++) { mn = min(mn, a[k][i] + a[k][j]); mx = max(mx, a[k][i] + a[k][j]); } ans += mn + mx; } } cout << ans; return 0; }