Educational Codeforces Round 56 Div. 2 翻車記
阿新 • • 發佈:2018-12-16
A:簽到。
B:僅當只有一種字元時無法構成非迴文串。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 1010 char getc(){char c=getchar();while ((c<'View CodeA'||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,cnt[26]; char s[N]; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ T=read(); while (T--) { scanf("%s",s+1);n=strlen(s+1); memset(cnt,0,sizeof(cnt));for (int i=1;i<=n;i++) cnt[s[i]-'a']++; int tot=0; for (int i=0;i<26;i++) if (cnt[i]) tot++; if (tot==1) cout<<-1<<endl; else { for (int i=0;i<26;i++) for (int j=1;j<=cnt[i];j++) putchar(i+'a'); cout<<endl; } } return 0; }
C:在滿足條件的前提下使每對數的差儘量大。
#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);} ll read() { ll 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; ll a[N],b[N],l,r; int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ n=read(); for (int i=1;i<=(n>>1);i++) a[i]=read(); l=0,r=1000000000000000000; for (int i=1;i<=(n>>1);i++) { b[i]=l,b[n-i+1]=a[i]-l; if (b[n-i+1]>r) b[i]+=b[n-i+1]-r,b[n-i+1]=r; l=b[i],r=b[n-i+1]; } for (int i=1;i<=n;i++) printf("%I64d ",b[i]); return 0; }View Code
D:二分圖染色,每個連通塊貢獻相乘即可。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 300010 #define P 998244353 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);} ll read() { ll 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,m,t,p[N],color[N],white,black; bool flag; 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 c) { if (flag==0) return; color[k]=c;if (c==0) white++;else black++; for (int i=p[k];i;i=edge[i].nxt) { if (flag==0) return; if (color[edge[i].to]==-1) dfs(edge[i].to,c^1); else if (color[edge[i].to]==c) {flag=0;return;} } } int ksm(int a,int k) { int s=1; for (;k;k>>=1,a=1ll*a*a%P)if (k&1) s=1ll*s*a%P; return s; } int main() { /*#ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif*/ T=read(); while (T--) { n=read(),m=read();flag=1;t=0; for (int i=1;i<=n;i++) p[i]=0,color[i]=-1; for (int i=1;i<=m;i++) { int x=read(),y=read(); addedge(x,y),addedge(y,x); } int cnt=0,ans=1; for (int i=1;i<=n;i++) if (color[i]==-1) { white=black=0,cnt++,dfs(i,0); ans=1ll*ans*(ksm(2,white)+ksm(2,black))%P; } if (flag==0) ans=0; printf("%d\n",ans); } return 0; }View Code
這都啥思博題啊20min切完。E一眼樹狀陣列套個權值線段樹,猶豫了一下ECR的E會不會這麼毒瘤,最後還是碼了。30min之後瘋狂RE22,因為空間根本開不下。這時候才想起來帶修改之後樹狀陣列套個treap和它複雜度是一樣的,還能回收下空間,於是又開始碼碼碼,過了20min終於A掉了。
E:將每個數在兩個排列裡的位置視為一個二維座標。現在要做到就是插點/刪點/矩形內點的個數。樹狀陣列套treap即可,需要回收空間。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<ctime> using namespace std; #define ll long long #define N 200010 #define lson tree[k].ch[0] #define rson tree[k].ch[1] 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);} ll read() { ll 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],b[N],root[N],pos[N][2],q[N<<5],head,tail,t; struct data{int ch[2],p,x,s; }tree[N<<5]; int up(int k){tree[k].s=tree[lson].s+tree[rson].s+1;} void move(int &k,int p) { int t=tree[k].ch[p]; tree[k].ch[p]=tree[t].ch[!p],tree[t].ch[!p]=k,up(k),up(t),k=t; } void INS(int &k,int x) { if (k==0) {if (head<tail) k=q[++head];else k=++t;tree[k].ch[0]=tree[k].ch[1]=0;tree[k].x=x;tree[k].p=rand();tree[k].s=1;return;} tree[k].s++; if (tree[k].x<=x) {INS(rson,x);if (tree[rson].p>tree[k].p) move(k,1);} else {INS(lson,x);if (tree[lson].p>tree[k].p) move(k,0);} } void DEL(int &k,int x) { if (tree[k].x==x) { if (lson==0||rson==0) {q[++tail]=k;k=lson|rson;return;} if (tree[lson].p>tree[rson].p) move(k,0),DEL(rson,x); else move(k,1),DEL(lson,x); } else if (tree[k].x<x) DEL(rson,x); else DEL(lson,x); up(k); } int find(int k,int x) { if (!k) return 0; if (tree[k].x<=x) return tree[lson].s+1+find(rson,x); else return find(lson,x); } void ins(int k,int x) { while (k<=n) INS(root[k],x),k+=k&-k; } void del(int k,int x) { while (k<=n) DEL(root[k],x),k+=k&-k; } int query(int k,int x) { int ans=0; while (k) ans+=find(root[k],x),k-=k&-k; return ans; } int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); #endif n=read(),m=read(); srand(time(0)); for (int i=1;i<=n;i++) a[i]=read(),pos[a[i]][0]=i; for (int i=1;i<=n;i++) b[i]=read(),pos[b[i]][1]=i; for (int i=1;i<=n;i++) ins(i,pos[a[i]][1]); for (int i=1;i<=m;i++) { int op=read(); if (op==1) { int la=read(),ra=read(),lb=read(),rb=read(); printf("%d\n",query(ra,rb)-query(ra,lb-1)-query(la-1,rb)+query(la-1,lb-1)); } else { int x=read(),y=read(); del(pos[b[x]][0],x),del(pos[b[y]][0],y), ins(pos[b[x]][0],y),ins(pos[b[y]][0],x); swap(b[x],b[y]); } } return 0; }View Code
G:將兩點間曼哈頓距離的絕對值展開討論,可以發現對於每種情況,兩點每維座標的貢獻與其原來該維座標的關係都是相同的(即正或負),於是線段樹暴力維護2k種狀態即可。我也不知道為什麼兩個樹套樹我只寫了50min(bit套樹根本就沒什麼碼量吧),一個裸的線段樹我能寫40min。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> #include<ctime> 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,m,k,a[N][5]; struct data{int l,r,f[32],g[32]; }tree[N<<2]; void dfs(int node,int x,int p,int s,int sum) { if (p==k) {tree[node].f[sum]=tree[node].g[sum]=s;return;} dfs(node,x,p+1,s-a[x][p],sum); dfs(node,x,p+1,s+a[x][p],sum|(1<<p)); } data merge(data x,data y) { data u;u.l=x.l,u.r=y.r; for (int i=0;i<(1<<k);i++) u.f[i]=max(x.f[i],y.f[i]),u.g[i]=min(x.g[i],y.g[i]); return u; } void build(int k,int l,int r) { tree[k].l=l,tree[k].r=r; if (l==r) {dfs(k,l,0,0,0);return;} int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); tree[k]=merge(tree[k<<1],tree[k<<1|1]); } void modify(int k,int x) { if (tree[k].l==tree[k].r) {dfs(k,x,0,0,0);return;} int mid=tree[k].l+tree[k].r>>1; if (x<=mid) modify(k<<1,x); else modify(k<<1|1,x); tree[k]=merge(tree[k<<1],tree[k<<1|1]); } data query(int k,int l,int r) { if (tree[k].l==l&&tree[k].r==r) return tree[k]; int mid=tree[k].l+tree[k].r>>1; if (r<=mid) return query(k<<1,l,r); else if (l>mid) return query(k<<1|1,l,r); else return merge(query(k<<1,l,mid),query(k<<1|1,mid+1,r)); } int main() { n=read(),k=read(); for (int i=1;i<=n;i++) for (int j=0;j<k;j++) a[i][j]=read(); build(1,1,n); m=read(); for (int i=1;i<=m;i++) { int op=read(); if (op==1) { int x=read(); for (int j=0;j<k;j++) a[x][j]=read(); modify(1,x); } else { int l=read(),r=read(); data x=query(1,l,r); int ans=0; for (int i=0;i<(1<<k);i++) ans=max(ans,x.f[i]-x.g[i]); printf("%d\n",ans); } } }View Code
F:沒看。
坐等fst。