10.5 考试 (感觉比较难)
T1
正解是 建26顆線段樹(shù),但是他們有人被卡常了...
還是分塊大法好,跑的最快
直接記錄下每一個(gè)塊 26個(gè)字母出現(xiàn)次數(shù),再打上升序還是降序的標(biāo)記
畢竟考試調(diào)了兩個(gè)小時(shí)呢23333
?
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> #define dd double #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long using namespace std; inline char readchar() {char q=getchar();while(q<'a'||q>'z')q=getchar();return q; } inline int read() {char q=getchar();int ans=0;while(q<'0'||q>'9')q=getchar();while(q>='0'&&q<='9'){ans=ans*10+q-'0';q=getchar();}return ans; } const int N=100006;int n,m,fen; int s[N];int dui[N],L[1006],R[1006],len[1006]; int num[1006][36],flag[1006];int t[36];inline void pushdown(int x) {if(flag[x]==-1)return ;int now;if(flag[x]==1){now=L[x];for(int i=0;i<26;++i)while(num[x][i])s[now++]=i,--num[x][i];}else{now=R[x];for(int i=0;i<26;++i)while(num[x][i])s[now--]=i,--num[x][i];}flag[x]=-1; }inline void pushup(int x) {mem(num[x],0);for(int i=L[x];i<=R[x];++i)++num[x][s[i]]; }inline void get_sum(int l,int r) {int q1=min(r,R[dui[l]]);pushdown(dui[l]);for(int i=l;i<=q1;++i)++t[s[i]];if(dui[l]!=dui[r]){pushdown(dui[r]);for(int i=L[dui[r]];i<=r;++i)++t[s[i]];}for(int i=dui[l]+1;i<dui[r];++i)for(int j=0;j<26;++j)t[j]+=num[i][j]; }inline void changesh(int l,int r) {get_sum(l,r);int q1=min(r,R[dui[l]]),now1,now2,temp;now1=0;now2=l;while(now2<=q1){while(!t[now1])++now1;s[now2]=now1;++now2;--t[now1];}pushup(dui[l]);for(int i=dui[l]+1;i<dui[r];++i){flag[i]=1;mem(num[i],0);now2=0;while(now2<len[i]){while(!t[now1])++now1;temp=min(len[i]-now2,t[now1]);num[i][now1]+=temp;now2+=temp;t[now1]-=temp;}}if(dui[l]!=dui[r]){now2=L[dui[r]];while(now2<=r){while(!t[now1])++now1;s[now2]=now1;++now2;--t[now1];}pushup(dui[r]);} }inline void changexi(int l,int r) {get_sum(l,r);int q1=max(l,L[dui[r]]),now1,now2,temp;now1=0;now2=r;while(now2>=q1){while(!t[now1])++now1;s[now2]=now1;--now2;--t[now1];}pushup(dui[r]);for(int i=dui[r]-1;i>dui[l];--i){flag[i]=0;for(int j=0;j<26;++j)num[i][j]=0;now2=0;while(now2<len[i]){while(!t[now1])++now1;temp=(len[i]-now2<t[now1]?len[i]-now2:t[now1]);num[i][now1]+=temp;now2+=temp;t[now1]-=temp;}}if(dui[l]!=dui[r]){now2=R[dui[l]];while(now2>=l){while(!t[now1])++now1;s[now2]=now1;--now2;--t[now1];}pushup(dui[l]);} }inline void out11() {for(int i=1;i<=dui[n];++i)pushdown(i);for(int i=1;i<=n;++i)printf("%c",s[i]+'a'); }int main(){//freopen("T1.in","r",stdin);//freopen("T1.out","w",stdout);mem(flag,-1);n=read();m=read();//fen=(int)ceil(sqrt((dd)n*13.5+0.5));fen=(int)ceil(sqrt(n+0.5));for(int i=1;i<=n;++i){s[i]=readchar()-'a';dui[i]=(i-1)/fen+1;++num[dui[i]][s[i]];}for(int i=1;i<=dui[n];++i){L[i]=(i-1)*fen+1;R[i]=min(n,i*fen);len[i]=R[i]-L[i]+1;}int op,l0,r0,now;for(int i=1;i<=m;++i){l0=read();r0=read();op=read();if(l0>r0)swap(l0,r0);if(op==1)changesh(l0,r0);elsechangexi(l0,r0);}out11(); }] T1?
T2
考試執(zhí)著的認(rèn)為是 容斥,也想過(guò)dp,但是覺(jué)得就是...(容斥個(gè)??)
f[i][j] 前i列中選了j列右區(qū)間的方案數(shù)
考慮 第i列選右區(qū)間還是不選 再考慮左區(qū)間選的方案數(shù),用排列計(jì)算
?
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=3006; const int mod=998244353;ll jie[N],jieni[N],ni[N];void chu() {ni[1]=1;for(int i=2;i<N;++i)ni[i]=(ll)(mod-mod/i)*ni[mod%i]%mod;jie[0]=jieni[0]=1;for(int i=1;i<N;++i){jie[i]=jie[i-1]*i%mod;jieni[i]=jieni[i-1]*ni[i]%mod;} }inline ll A(int n,int m) {if(n<m)return 0;return jie[n]*jieni[n-m]%mod; }int n,m; int l[N],r[N]; ll f[N][N];int jil[N],prel[N],jir[N],prer[N];void dp() {f[0][0]=1;for(int i=1;i<=m;++i)for(int j=0;j<=n;++j){f[i][j]=(f[i][j]+f[i-1][j])%mod;if(j>0&&prer[i]-(j-1)>=0)//if(j>0){//printf("i=%d j=%d\n",i,j);f[i][j]=(f[i][j]+f[i-1][j-1]*(prer[i]-(j-1))%mod )%mod;}if(jil[i]){if(j+prel[i]>i)f[i][j]=0;elsef[i][j]=f[i][j]*A(i-j-prel[i-1],jil[i])%mod;}} }int main(){//freopen("in.in","r",stdin);chu();scanf("%d%d",&n,&m);//printf("n=%d\n",n);for(int i=1;i<=n;++i){scanf("%d%d",&l[i],&r[i]);++jil[l[i]];++jir[r[i]];}for(int j=1;j<=m;++j){prel[j]=prel[j-1]+jil[j];prer[j]=prer[j-1]+jir[j];}dp();/*printf("\n");for(int i=1;i<=m;++i){for(int j=1;j<=n;++j)printf("%lld ",f[i][j]);printf("\n");}*/cout<<f[m][n]; } T2?
T3
對(duì)手的變換其實(shí)是把 x循環(huán)左移一位...
而x異或一部分?jǐn)?shù)后再左移,相當(dāng)于x先左移,前i個(gè)數(shù)異或和再左移
之后就是:
給m+1個(gè)數(shù),選一個(gè)x,使得x與m+1個(gè)數(shù)異或和最小值最大
這個(gè)可以把m+1個(gè)數(shù)建一顆0/1trie
然后在樹(shù)上走
如果這個(gè)節(jié)點(diǎn)0/1兒子都有,你肯定得選1/0是最后這一位異或是0 (你要保證最小值)
如果只有一個(gè)兒子,這一位你要選一個(gè)數(shù) 使其最后異或是1 (最大值)
之后在得到的m+1個(gè)數(shù)里 找到ans
?
#include <cstdio> #include <cstring> #include <iostream> #include <cstdlib> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int M=100006; struct son {son* ch[2];son(){ch[0]=ch[1]=NULL;} }*root;int n,m,maxp; int a[M],pre[M];int con; int b[M];void add(int x) {int temp;son *now=root;for(int i=n-1;i>=0;--i){temp=0;if( (1<<i)&x )temp=1;if(now->ch[temp]==NULL)now->ch[temp]=new son();now=now->ch[temp];} }inline int move(int x) {return ((1<<(n-1))&x)?(((x<<1)&maxp)|1):((x<<1)&maxp); }inline int move2(int x) {return (1&x)?((x>>1)|(1<<(n-1))):(x>>1); }void dfs(son *x,int h,int now) {//printf("h=%d now=%d\n",h,now);if(h==-1){b[++con]=now;return ;}if(x->ch[0]!=NULL&&x->ch[1]!=NULL){dfs(x->ch[0],h-1,now);dfs(x->ch[1],h-1,now);}elseif(x->ch[0]!=NULL)dfs(x->ch[0],h-1,now|(1<<h));elseif(x->ch[1]!=NULL)dfs(x->ch[1],h-1,now|(1<<h));return ; }void out11() {printf("%d %d %d\n",move(1),move(2),move(3));printf("\n");for(int i=1;i<=m;++i)printf("%d ",pre[i]);printf("\n");for(int i=1;i<=con;++i)printf("%d ",b[i]);printf("\n"); }int main(){//freopen("in.in","r",stdin);//freopen("big2.in","r",stdin);scanf("%d%d",&n,&m);maxp=(1<<n)-1;for(int i=1;i<=m;++i){scanf("%d",&a[i]);pre[i]=pre[i-1]^a[i];}b[++con]=pre[m];for(int i=1;i<=m;++i)b[++con]=move(pre[i])^(pre[m]^pre[i]);root=new son();for(int i=1;i<=con;++i)add(b[i]);con=0;dfs(root,n-1,0);int mx=-1,num=0;for(int i=1;i<=con;++i){if(mx<b[i]){mx=b[i];num=1;}elseif(mx==b[i])++num;}//out11();printf("%d\n%d",mx,num); } T3?
這次考試個(gè)人覺(jué)得比較難
第一題調(diào)的時(shí)間太長(zhǎng),代碼能力有待提升....
?
轉(zhuǎn)載于:https://www.cnblogs.com/A-LEAF/p/7631274.html
總結(jié)
以上是生活随笔為你收集整理的10.5 考试 (感觉比较难)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Codeforces Round #4
- 下一篇: 【u018】电车