首页 > 其他 > 详细

xjoi 省选模拟赛_13

时间:2017-01-12 10:59:35      阅读:262      评论:0      收藏:0      [点我收藏+]

昨晚停电 xj的评测姬go die了 上午没有题 认(lang)真(de)学(fei)习(qi)  下午意识模糊之际 xy进来放了一套题 

奇毒无比 感到了深深的绝望::

T1

技术分享

大数据结构题 一觉醒来 感觉GG  reverse 操作可以维护 正反两个哈希值 上splay 查询二分判断  

#include <bits/stdc++.h>
#define N 1100010
using namespace std;
typedef unsigned long long ull;
const ull xx=23333;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0&&ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
int n,m,Q,lsd1,lsd2,pla[N],plb[N],k;
int A[N],B[N],faa[N],fab[N],rt1,rt2;
int ca[N][2],cb[N][2],sza[N],szb[N];
bool rev[N];
ull hasha[N],hashb[N],hashr[N];
ull pows[N];
inline void pushdown(int rt)
{
    if(rev[rt])
    {
        swap(hashr[rt],hasha[rt]);
        rev[ca[rt][0]]^=1;
        rev[ca[rt][1]]^=1;
        swap(ca[rt][0],ca[rt][1]);
        rev[rt]=0;
    }
}
inline void updata1(int mid)
{
    sza[mid]=sza[ca[mid][0]]+sza[ca[mid][1]]+1;
    pushdown(ca[mid][0]);pushdown(ca[mid][1]);
    hasha[mid]=pows[sza[ca[mid][0]]]*A[mid]+hasha[ca[mid][0]]+pows[sza[ca[mid][0]]+1]*hasha[ca[mid][1]];
    hashr[mid]=pows[sza[ca[mid][1]]]*A[mid]+hashr[ca[mid][1]]+pows[sza[ca[mid][1]]+1]*hashr[ca[mid][0]];
}
inline void updata2(int mid)
{
    szb[mid]=szb[cb[mid][0]]+szb[cb[mid][1]]+1;
    hashb[mid]=pows[szb[cb[mid][0]]]*B[mid]+hashb[cb[mid][0]]+pows[szb[cb[mid][0]]+1]*hashb[cb[mid][1]];   
}
int built1(int fa,int l,int r)
{
    if(l>r) return 0;
    int mid=(l+r)>>1,g=mid;sza[mid]=1;
    hasha[mid]=hashr[mid]=A[mid];
    ca[g][0]=built1(mid,l,mid-1);ca[g][1]=built1(mid,mid+1,r);
    updata1(mid);
    faa[mid]=fa; return g;
}
int built2(int fa,int l,int r)
{
    if(l>r) return 0;
    int mid=(l+r)>>1,g=mid;szb[mid]=1;
    hashb[mid]=B[mid];
    cb[g][0]=built2(mid,l,mid-1);cb[g][1]=built2(mid,mid+1,r);
    updata2(mid);
    fab[mid]=fa; return g; 
}
// splay B
void rotateb(int x,int &k)
{
    int y=fab[x],z=fab[y],l,r;
    l=(cb[y][1]==x);r=l^1;
    if(y==k)k=x;
    else cb[z][cb[z][1]==y]=x;
    fab[cb[x][r]]=y;fab[y]=x;fab[x]=z;
    cb[y][l]=cb[x][r];cb[x][r]=y;
    updata2(y);updata2(x);
}
void splayb(int x,int &k)
{
    while(x!=k)
    {
        int y=fab[x],z=fab[y];
        if(y!=k)
        {
            if((cb[y][0]==x)^(cb[z][0]==y))rotateb(x,k);
            else rotateb(y,k);
        }
        rotateb(x,k);
    }
}
int findb(int now,int rk)
{
    if(szb[cb[now][0]]+1==rk) return now;
    if(szb[cb[now][0]]>=rk) findb(cb[now][0],rk);
    else findb(cb[now][1],rk-szb[cb[now][0]]-1);
}
void splitb(int l,int r)
{
    int x=findb(rt2,l-1),y=findb(rt2,r+1);
    splayb(x,rt2);
    splayb(y,cb[rt2][1]);
    updata2(rt2);
}
// splay A
void rotatea(int x,int &k)
{
    int y=faa[x],z=faa[y],l,r;
    pushdown(z); pushdown(y);
    l=(ca[y][1]==x);r=l^1;
    if(y==k)k=x;
    else ca[z][ca[z][1]==y]=x;
    faa[ca[x][r]]=y;faa[y]=x;faa[x]=z;
    ca[y][l]=ca[x][r];ca[x][r]=y;
    updata1(y);updata1(x);
}
void splaya(int x,int &k)
{
    while(x!=k)
    {
        int y=faa[x],z=faa[y];
        if(y!=k)
        {
            if((ca[y][0]==x)^(ca[z][0]==y))rotatea(x,k);
            else rotatea(y,k);
        }
        rotatea(x,k);
    }
}
int finda(int now,int rk)
{
    pushdown(now);
    if(sza[ca[now][0]]+1==rk) return now;
    if(sza[ca[now][0]]>=rk) finda(ca[now][0],rk);
    else finda(ca[now][1],rk-sza[ca[now][0]]-1);
}
void splita(int l,int r)
{
    int x=finda(rt1,l-1),y=finda(rt1,r+1);
    splaya(x,rt1);
    splaya(y,ca[rt1][1]);
    updata1(rt1);
}
void erase()
{
    int xs; scanf("%d",&xs);
    int x=finda(rt1,xs); splaya(x,rt1);
    int rk=sza[ca[rt1][0]]+1;
    int y=finda(rt1,rk+2); splaya(y,ca[rt1][1]);
    ca[ca[rt1][1]][0]=0;updata1(ca[rt1][1]);
    updata1(rt1);n--;
}
void insert()
{
    int xs,ys; scanf("%d%d",&xs,&ys);
    int x=finda(rt1,xs); splaya(x,rt1);
    A[++lsd1]=ys; int rk=sza[ca[rt1][0]]+1;
    int y=finda(rt1,rk+1); splaya(y,ca[rt1][1]);
    faa[lsd1]=y; ca[y][0]=lsd1; updata1(lsd1);
    updata1(y); updata1(rt1); n++;
}
bool check(int l,int r,int len)
{
    splita(l,l+len-1);
    splitb(r,r+len-1);
    if(hasha[ca[ca[rt1][1]][0]]==hashb[cb[cb[rt2][1]][0]])
        return 1;
    return 0;
}
int query()
{
    int l,r; scanf("%d %d",&l,&r); l++;r++;
    int L=1,R=min(n-l+2,m-r+2),ans=0;
    while(L<=R)
    {
        int mid=(L+R)>>1;
        if(check(l,r,mid)) ans=max(ans,mid),L=mid+1;
        else R=mid-1;
    }
    return ans;
}
void reverse()
{
    int l,r; scanf("%d%d",&l,&r);l++;r++;
    if(l>r) swap(l,r);
    splita(l,r); int g=ca[ca[rt1][1]][0];
    rev[g]^=1; pushdown(g);
    updata1(faa[g]); updata1(rt1);
}
int main()
{
 //   freopen("read.in","r",stdin);
    n=read();m=read();
    for(int i=2;i<=n+1;i++) scanf("%d",&A[i]);A[1]=0;A[n+2]=0; lsd1=n+2;
    for(int i=2;i<=m+1;i++) scanf("%d",&B[i]);B[1]=0;B[m+2]=0; lsd2=m+2;
    for(int i=1;i<=4;i++) scanf("%d",&k),Q+=k;
    pows[0]=1;for(int i=1;i<=max(n,m)+3;i++)  pows[i]=pows[i-1]*xx;
    rt1=built1(0,1,n+2);rt2=built2(0,1,m+2);
    for(int i=1;i<=Q;i++)
    {
        char com[10];
        scanf("%s",com);
        if(com[0]==Q) printf("%d\n",query());
        else if(com[0]==D) erase();
        else if(com[0]==I) insert();
        else if(com[0]==R) reverse();
    }  
    return 0;
}

一开始wa 80 在updata 里面 需要两个儿子的hash 值 需要puahdown

 

技术分享

太神了 不会做 30分暴力还是py的  听说是基环树重构  然而去年我还在玩泥巴  爆炸

开了坑 以后再填

 

技术分享

这题是数论未解之谜!!!!  不过只需要构造方案  前两个点 强行暴力搜搜搜 后面交空文件能拿一分

oeis一发仍毫无软用 药丸药丸

xjoi 省选模拟赛_13

原文:http://www.cnblogs.com/wcz112/p/6275056.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!