NOIP2017模拟day1 T3 string splay 置换

来源:互联网 发布:疯帽子雾化器做丝数据 编辑:程序博客网 时间:2024/06/05 05:07



先是裸的区间翻转 然后求字典序第k小的串

区间翻转用splay,字典序的话也很好搞

很容易看出,同一个置换循环节里的字符一定相同

所以搞完之后,做一个26进制数就好了


26进制数脑残版。。。

#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=500100;int ch[N][2],size[N],fa[N],root;bool rev[N];inline void pushup(int k){size[k]=1+size[ch[k][0]]+size[ch[k][1]];}inline void pushdown(int k){if(rev[k]){rev[ch[k][1]]^=1,rev[ch[k][0]]^=1;swap(ch[k][1],ch[k][0]);rev[k]=0;}}void build(int l,int r,int pre){if(l>r)return ;int mid=(l+r)>>1;fa[mid]=pre;mid>pre?ch[pre][1]=mid:ch[pre][0]=mid;build(l,mid-1,mid);build(mid+1,r,mid);pushup(mid);}int find(int k){int now=root;while(k){pushdown(now);if(size[ch[now][0]]>=k)now=ch[now][0];else if(size[ch[now][0]]+1<k)k-=size[ch[now][0]]+1,now=ch[now][1];else return now;}return now;}inline void rotate(int x,int &k){int y=fa[x],z=fa[y],l,r;l=(ch[y][1]==x);r=l^1; if(y==k)k=x;else ch[z][0]==y?ch[z][0]=x:ch[z][1]=x;fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y;pushup(y);pushup(x);}void splay(int x,int &k){int y,z;while(x^k){y=fa[x];z=fa[y];if(y^k){if((ch[z][0]==y)^(ch[y][0]==x))rotate(x,k);else rotate(y,k);}rotate(x,k);}}void rever(int l,int r){int x=find(l),y=find(r+2);splay(x,root);splay(y,ch[x][1]);rev[ch[y][0]]^=1;}int n;ll K,bas[N];char s[N],ans[N];int b[N],bel[N],block,st[N];bool book[N];void solve(){register int i,now,top=0;for(i=1;i<=n;++i)if(!bel[i]){block++;now=i;while(!bel[now]){bel[now]=block;now=b[now];}}for(i=1;i<=n;++i)if(s[i]!='?')ans[bel[i]]=s[i];for(i=1;i<=n;++i)if(!ans[bel[i]]&&!book[bel[i]])book[bel[i]]=1,st[++top]=bel[i];for(i=top;i;i--)ans[st[i]]='a'+K%26,K/=26;}int main(){n=read();int Q=read();scanf("%lld",&K);K--;scanf("%s",s+1);build(1,n+2,0);root=(n+3)>>1;register int i,l,r;while(Q--){l=read();r=read();rever(l,r);}for(i=1;i<=n;++i)b[i]=find(i+1)-1;solve();for(i=1;i<=n;++i)putchar(ans[bel[i]]);puts("");return 0;}/*12 1 4ztrs?a?isred5 7ztrsdadisred*/


26进制数普通版。。。

#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=500100;int ch[N][2],size[N],fa[N],root;bool rev[N];inline void pushup(int k){size[k]=1+size[ch[k][0]]+size[ch[k][1]];}inline void pushdown(int k){if(rev[k]){rev[ch[k][1]]^=1,rev[ch[k][0]]^=1;swap(ch[k][1],ch[k][0]);rev[k]=0;}}void build(int l,int r,int pre){if(l>r)return ;int mid=(l+r)>>1;fa[mid]=pre;mid>pre?ch[pre][1]=mid:ch[pre][0]=mid;build(l,mid-1,mid);build(mid+1,r,mid);pushup(mid);}int find(int k){int now=root;while(k){pushdown(now);if(size[ch[now][0]]>=k)now=ch[now][0];else if(size[ch[now][0]]+1<k)k-=size[ch[now][0]]+1,now=ch[now][1];else return now;}return now;}inline void rotate(int x,int &k){int y=fa[x],z=fa[y],l,r;l=(ch[y][1]==x);r=l^1; if(y==k)k=x;else ch[z][0]==y?ch[z][0]=x:ch[z][1]=x;fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y;pushup(y);pushup(x);}void splay(int x,int &k){int y,z;while(x^k){y=fa[x];z=fa[y];if(y^k){if((ch[z][0]==y)^(ch[y][0]==x))rotate(x,k);else rotate(y,k);}rotate(x,k);}}void rever(int l,int r){int x=find(l),y=find(r+2);splay(x,root);splay(y,ch[x][1]);rev[ch[y][0]]^=1;}int n;ll K,bas[N];char s[N],ans[N];int b[N],bel[N],block,st[N];bool book[N];inline int get_pow(ll x){int l=0,r=14,res=0;while(l<=r){int mid=(l+r)>>1;bas[mid]<=x?(l=mid+1,res=mid):r=mid-1;}return res;}void solve(){register int i,now,top=0;for(i=1;i<=n;++i)if(!bel[i]){block++;now=i;while(!bel[now]){bel[now]=block;now=b[now];}}for(i=1;i<=n;++i)if(s[i]!='?')ans[bel[i]]=s[i];for(i=1;i<=n;++i)if(!ans[bel[i]]&&!book[bel[i]])book[bel[i]]=1,st[++top]=bel[i];bas[0]=1;for(i=1;i<=14;++i)bas[i]=bas[i-1]*26;K--;while(K){now=get_pow(K);ans[st[top-now]]='a'+K/bas[now];K-=bas[now]*(K/bas[now]);}for(i=1;i<=top;++i)if(!ans[st[i]])ans[st[i]]='a';}int main(){n=read();int Q=read();scanf("%lld",&K);scanf("%s",s+1);build(1,n+2,0);root=(n+3)>>1;register int i,l,r;while(Q--){l=read();r=read();rever(l,r);}for(i=1;i<=n;++i)b[i]=find(i+1)-1;solve();for(i=1;i<=n;++i)putchar(ans[bel[i]]);puts("");return 0;}/*12 1 4ztrs?a?isred5 7ztrsdadisred*/

原创粉丝点击