Educational Codeforces Round 58 Div. 2 自閉記
阿新 • • 發佈:2019-01-12
明明多個幾秒就能場上AK了。自閉。
A:簽到。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'View Codea'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar();return x*f; } int T,l,r,d; signed main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #endif*/ T=read(); while (T--) { l=read(),r=read(),d=read(); if (d<l) cout<<d<<endl; else cout<<1ll*(r/d+1)*d<<endl; } return 0; //NOTICE LONG LONG!!!!! }
B:簽到。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 500010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n; char s[N]; signed main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #endif*/ scanf("%s",s+1);n=strlen(s+1); bool flag=0;int x=n+1,y=0; for (int i=1;i<=n;i++) { if (s[i]=='[') flag=1; if (s[i]==':') if (flag) {x=i;break;} } flag=0; for (int i=n;i>=1;i--) { if (s[i]==']') flag=1; if (s[i]==':') if (flag) {y=i;break;} } if (x>=y) cout<<-1; else { int ans=4; for (int i=x+1;i<y;i++) if (s[i]=='|') ans++; cout<<ans; } return 0; //NOTICE LONG LONG!!!!! }View Code
C:wa了無數發。按左端點排序後找一個連續且和其他線段不相交的線段集即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 100010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int T,n,ans[N]; struct data { int l,r,i; bool operator <(const data&a) const { return l<a.l; } }a[N]; signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #endif T=read(); while (T--) { n=read(); for (int i=1;i<=n;i++) a[i].l=read(),a[i].r=read(),a[i].i=i; sort(a+1,a+n+1); bool flag=0;a[n+1].l=100000000; int t=1,x=a[1].r; while (t<n&&a[t+1].l<=x) t++,x=max(x,a[t].r); if (t==n) cout<<-1<<endl; else { for (int i=1;i<=t;i++) ans[a[i].i]=1; for (int i=t+1;i<=n;i++) ans[a[i].i]=2; for (int i=1;i<=n;i++) printf("%d ",ans[i]); cout<<endl; } } return 0; //NOTICE LONG LONG!!!!! }View Code
E:這才是真簽到吧?wa了一發自閉啊?
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 500010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int m,u,v; signed main() { #ifndef ONLINE_JUDGE freopen("b.in","r",stdin); freopen("b.out","w",stdout); const char LL[]="%I64d\n"; #endif m=read(); while (m--) { char c=getchar();while (c!='+'&&c!='?') c=getchar(); int x=read(),y=read();if (x>y) swap(x,y); if (c=='+') { u=max(u,x),v=max(y,v); } else { if (x>=u&&y>=v) printf("YES\n"); else printf("NO\n"); } } return 0; //NOTICE LONG LONG!!!!! }View Code
D:如果路徑經過某點,最後所得的路徑gcd顯然是該點某些質因子的倍數。對此dp即可。一發wa on 3,3可是樣例啊?自閉了啊?
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 200010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,a[N],p[N],f[N][30],prime[N][30],t,ans; struct data{int to,nxt; }edge[N<<1]; void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;} void dfs(int k,int from) { for (int i=p[k];i;i=edge[i].nxt) if (edge[i].to!=from) { dfs(edge[i].to,k); for (int x=1;x<=prime[edge[i].to][0];x++) for (int y=1;y<=prime[k][0];y++) if (prime[edge[i].to][x]==prime[k][y]) { ans=max(ans,f[k][y]+f[edge[i].to][x]+1); f[k][y]=max(f[k][y],f[edge[i].to][x]+1); } } } signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #endif n=read(); for (int i=1;i<=n;i++) a[i]=read(); bool flag=1; for (int i=1;i<=n;i++) if (a[i]!=1) flag=0; if (flag) {cout<<0;return 0;} for (int i=1;i<n;i++) { int x=read(),y=read(); addedge(x,y),addedge(y,x); } for (int i=1;i<=n;i++) { for (int j=2;j*j<=a[i];j++) if (a[i]%j==0) { prime[i][++prime[i][0]]=j; while (a[i]%j==0) a[i]/=j; } if (a[i]>1) prime[i][++prime[i][0]]=a[i]; } dfs(1,1); cout<<ans+1; return 0; //NOTICE LONG LONG!!!!! }View Code
G:一眼線性基,然後就往別的方面想了。自閉了半天直接亂搞求個字首和搞了個線性基上去就pp了。冷靜了半天正確性何在。事實上劃分序列相當於選出一些字首和,這是一個裸到不行的線性基。注意雖然最後一個字首和應該是必須選的,但是不考慮也不會造成什麼影響(吧)。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 200010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,a[N],base[32],ans; signed main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d\n"; #endif n=read(); for (int i=1;i<=n;i++) a[i]=a[i-1]^read(); if (a[n]==0) {cout<<-1;return 0;} for (int i=1;i<=n;i++) for (int j=30;~j;j--) if (a[i]&(1<<j)) { if (base[j]) a[i]^=base[j]; else {base[j]=a[i],ans++;break;} } cout<<ans; return 0; //NOTICE LONG LONG!!!!! }View Code
F:隨便都知道是二分答案。但是nmlog顯然有些吃力。考慮random_shuffle一發,每次記錄當前需要的最大容量,考慮下一輛卡車時先判斷當前容量是否能滿足其需求,如果不行再二分一下。這樣複雜度大約是nm+nlogmlogV,因為只需要對所需容量的單調棧中的卡車進行二分,而排列又是隨機的。複雜度證明似乎在一篇cfblog裡看到過。(突然發現整個idea都在這篇blog裡https://codeforces.com/blog/entry/62602)一開始又沒注意到要開long long,交一發in queue了半天,然後wa on 3,結果改了一發又沒改全,交一發再次in queue了半天,接著wa on 3。然後就只剩20s了,手速不行,就,自閉了。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<ctime> using namespace std; #define ll long long #define N 410 #define M 250010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;} int gcd(int n,int m){return m==0?n:gcd(m,n%m);} int read() { int 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<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } int n,m,a[N]; ll ans; struct data{int s,f,c,r; }b[M]; bool check(ll k,int i) { ll cur=k;int cnt=0; for (int j=b[i].s;j<b[i].f;j++) { if (cur>=1ll*b[i].c*(a[j+1]-a[j])) cur-=1ll*b[i].c*(a[j+1]-a[j]); else { cur=k,cnt++; if (cur>=1ll*b[i].c*(a[j+1]-a[j])) cur-=1ll*b[i].c*(a[j+1]-a[j]); else return 0; } if (cnt>b[i].r) return 0; } return 1; } signed main() { #ifndef ONLINE_JUDGE freopen("b.in","r",stdin); freopen("b.out","w",stdout); const char LL[]="%I64d\n"; #endif srand(time(0)); n=read(),m=read(); for (int i=1;i<=n;i++) a[i]=read(); for (int i=1;i<=m;i++) b[i].s=read(),b[i].f=read(),b[i].c=read(),b[i].r=read(); random_shuffle(b+1,b+m+1); for (int i=1;i<=m;i++) if (!check(ans,i)) { ll l=ans+1,r=1000000000000000000ll; while (l<=r) { ll mid=l+r>>1; if (check(mid,i)) ans=mid,r=mid-1; else l=mid+1; } } cout<<ans; return 0; //NOTICE LONG LONG!!!!! }View Code