耗时最长代码合集

CF Sasha and Array(最长注释,长达50行)

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#define num ch-'0'
#define int long long
using namespace std;
typedef long long ll;
const int N=100000+10;
const int mod=1e9+7;
void read(int &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=num;isdigit(ch=getchar());x=x*10+num);
}
void red(ll &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=num;isdigit(ch=getchar());x=x*10+num);
}
int n,m;
ll a[N];
struct T{
    ll a[3][3];
    //T() {memset(a,0,sizeof a);laz[1][1]=laz[2][2]=1;}
    void clear(){
        //memset(a,0,sizeof a);
        for(int i=0;i<3;i++)
         for(int j=0;j<3;j++)
          a[i][j]=0;
    }
    void init(){
        a[1][1]=a[2][2]=1;
    }
    bool empty(){
        if(a[1][1]!=1) return 0;
        if(a[1][2]!=0) return 0;
        if(a[2][1]!=0) return 0;
        if(a[2][2]!=1) return 0;
        return 1;
    }
    T operator + (T b){
        T c;c.clear();
        for(int i=1;i<=2;i++)
          for(int j=1;j<=2;j++)
           c.a[i][j]=(c.a[i][j]+b.a[i][j]+a[i][j])%mod;
        return c;
    }/*void print(){
        for(int i=1;i<=2;i++)
        {
            for(int j=1;j<=2;j++)
             cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }*/
    T operator * (T b){
        T c;c.clear();
        for(int i=1;i<=2;i++)
         for(int k=1;k<=2;k++)
          for(int j=1;j<=2;j++)
           c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mod;
        //c.print();
        return c;
    }
   
}t[4*N],laz[4*N],M,B;
T qm(T a,ll y){
    T ret,base;
    ret.clear(),ret.init();
    while(y){
        if(y&1) ret=ret*a;
        a=a*a;
        y>>=1;
    }
    return ret;
}

void pushup(int x){
    t[x]=t[x<<1]+t[x<<1|1];
}
void build(int x,int l,int r){

    laz[x].clear();laz[x].init();
    t[x].clear();
    if(l==r){
        
        t[x]=qm(M,a[l]-1);
        //cout<<l<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
        //laz[x].print();
        return;
    }
    //laz[x].clear(),laz[x].init();
    int mid=l+r>>1;
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    pushup(x);
//    if(l==1&&r==3){
//        cout<<" get "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
//    }
}
void pushdown(int x,int l,int r)
{
    //if(laz[x].empty()) return;
    //if(laz[x].a[1][1]==1&&laz[x].a[2][2]==1&&laz[x].a[2][1]==0&&laz[x].a[1][2]==0) return;
    if(laz[x].empty()) return;
    int ls=(x<<1),rs=(x<<1|1);
    //cout<<" here "<<l<<" "<<r<<endl;
    //if(l==10&&r==14) laz[x].print();
    //cout<<" before "<<endl;
    //t[ls].print(); puts("");t[rs].print();    
   // laz[x].print();
    //cout<<" ans "<<endl;
    //(t[ls]*laz[x]).print();
    t[ls]=t[ls]*laz[x];
    //cout<<" cc "<<endl;cc.print();
    //t[ls]=cc;
    //cout<<"ls:";t[ls].print();
    //T dd=t[rs]*laz[x];
    
    t[rs]=t[rs]*laz[x];
    //t[ls].print(),puts(""),t[rs].print();
    //cout<<"laz "<<laz[rs].pr
    laz[ls]=laz[ls]*laz[x];
    laz[rs]=laz[rs]*laz[x];
    //cout<<" after "<<endl;
   //  puts("");t[rs].print();
   // t[x].laz[1][1]=t[x].laz[2][2]=1;
   laz[x].clear();laz[x].init();
    //t[x].laz=0;
    
}
void update(int x,int l,int r,int L,int R,T c)
{
    //cout<<" ffff "<<l<<" "<<r<<" "<<endl;
    if(L<=l&&r<=R){
    //    cout<<" l and r "<<l<<" "<<r<<endl; 
    //    cout<<" laz1 "<<lz<<" laz2 "<<t[x].laz<<endl;
        t[x]=t[x]*c;
//        cout<<" lazy "<<t[x].laz<<endl;
        //t[x]=t[x]*c;
        laz[x]=laz[x]*c;
        //if(l==1&&r==5) laz[x].print();
        //if(L==8&&R==15) c.print();
        //if(l==10&&r==14) laz[x].print();
    //    if(l==1&&r==3){
    //    cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    //}
        return;
    }
    pushdown(x,l,r);
    int mid=l+r>>1;
    if(L<=mid) update(x<<1,l,mid,L,R,c);
    if(mid<R) update(x<<1|1,mid+1,r,L,R,c);
    pushup(x);
    //if(l==1&&r==3){
    //    cout<<" get222 "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    //}
}
T query(int x,int l,int r,int L,int R)
{
    //if(L==1&&R==3) cout<<"finding "<<l<<" "<<r<<endl;
    //cout<<" finding "<<l<<" "<<r<<endl;
    //if(l==1&&r==5) laz[x].print();
    if(L<=l&&r<=R){
        
       // if(l==4&&r==5) t[x].print();
        return t[x];
    }
    //cout<<" dfdfdfdfd "<<l<<" "<<r<<endl;
    pushdown(x,l,r);
    //cout<<" fdfdfdf "<<l<<" "<<r<<endl;
    T ret;ret.clear();
    //ret.print();
    int mid=l+r>>1;
    //query(x<<1,l,mid,L,R).print();
    if(L<=mid) ret=ret+query(x<<1,l,mid,L,R);
    if(mid<R) ret=ret+query(x<<1|1,mid+1,r,L,R);
    //cout<<" after "<<l<<" "<<r<<" : "<<t[x].a[1][1]<<" "<<t[x].a[1][2]<<" "<<t[x].a[2][1]<<" "<<t[x].a[2][2]<<endl;
    return ret;
}
ll work(int l,int r)
{
    T ret;ret.clear();
    ret=B*query(1,1,n,l,r);
    return ret.a[1][1];
}
signed main()
{
    
    B.clear(),M.clear();
    B.a[1][1]=1;//B.a[1][2]=1;
    M.a[1][1]=M.a[1][2]=M.a[2][1]=1;
    //scanf("%I64d%I64d",&n,&m);
    read(n);read(m);
    for(int i=1;i<=n;i++) 
    red(a[i]);
    //scanf("%I64d",&a[i]);
    build(1,1,n);
    
    int op,l,r;
    ll z;
    while(m--){
       // scanf("%I64d",&op);
       //cout<<"mmmm "<<m<<endl;
       read(op);
        if(op==1){
            //scanf("%I64d%I64d%I64d",&l,&r,&z);
            read(l);read(r);red(z);
            //cout<<" before "<<z<<" "<<endl;
            T k;k=qm(M,z);
            //cout<<" after "<<z<<endl;
            //cout<<k.a[1][1]<<" "<<k.a[1][2]<<" "<<k.a[2][1]<<" "<<k.a[2][2]<<endl;
            update(1,1,n,l,r,k);
        }
        else{
            //scanf("%I64d%I64d",&l,&r);
            read(l);read(r);
            printf("%I64d\n",work(l,r));
        }
    }
    return 0;
}
Sasha and Array

尤其pushdown满篇注释,其实就错了两点:

1.数组越界了...后果:c++不会告诉你RE,只是不知道在哪里就卡崩了。

现象:莫名的错误;直接赋值出错,间接赋值没错;cout在前可以正确输出,操作一下别的什么东西,cout在后就错了。

死坑死坑死坑的。

2.注释太多,漏了laz之间的下放。。。。

以后,注释没用还是删掉一些为好。

 

洛谷P4208 [JSOI2008]最小生成树计数(182行 2.5h)

#include<bits/stdc++.h>
using namespace std;
const int mod=31011;
const int N=100+10;
const double eps=1e-8;
typedef long long ll;
int n,m;
int fa[N],ff[N];
struct node{
    int x,y;
    int val;
}bian[1000+20];
bool cmp(node a,node b){
    return a.val<b.val;
}
int fin(int x){
    if(fa[x]==x) return x;
    return fa[x]=fin(fa[x]);
}
int inf(int x){
    if(ff[x]==x) return x;
    return ff[x]=inf(ff[x]);
}
void mer(int x,int y){
    int k1=fin(x);
    int k2=fin(y);
    if(k1!=k2){
        fa[k1]=k2;
    }
}
bool cmp2(int a,int b){
    return fin(bian[a].x)<fin(bian[b].x);
}
struct tr{
    double f[N][N];
    int cnt;
    void init(){
        memset(f,0,sizeof f);cnt=0;
    }
    tr operator -(const tr &b){
        tr c;c.init();c.cnt=cnt;
        for(int i=1;i<=cnt;i++)
         for(int j=1;j<=cnt;j++) 
          c.f[i][j]=f[i][j]-b.f[i][j];
        return c;
    }
    void op(){
        cout<<endl;
        for(int i=1;i<=cnt;i++){
            cout<<i<<" | ";
            for(int j=1;j<=cnt;j++)
             cout<<f[i][j]<<" ";
            cout<<endl;
        }    
    }
};
ll gauss(tr S){
    int s=S.cnt;
    double a[N][N];
    memcpy(a,S.f,sizeof S.f);
    int sign=0;
    for(int i=1;i<=s;i++){
        int id=i;
        for(int j=i+1;j<=s;j++){
            if(fabs(a[j][i])>fabs(a[id][i])) id=j;
        }
        if(id!=i){
            for(int j=1;j<=s;j++)
             swap(a[i][j],a[id][j]);
        }
        for(int j=i+1;j<=s;j++){
            double ch=a[j][i]/a[i][i];
            for(int k=1;k<=s;k++){
                a[j][k]=a[j][k]-a[i][k]*ch;
            }
        }
    }
    double ret=1.0;
    for(int i=1;i<=s;i++) ret*=a[i][i];
    ll ans=(ll)(ret+eps+eps);
    ans=abs(ans);
    return ans%mod;
}
int mem[N],mems;
int edge[N],tot;
int du[N];
int li(int x){
    int k=lower_bound(mem+1,mem+mems+1,x)-mem;
    return k;
}
ll ans=1;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&bian[i].x,&bian[i].y,&bian[i].val);
    }    
    sort(bian+1,bian+m+1,cmp);
    for(int i=1;i<=m;i++){//mst
        int x=bian[i].x,y=bian[i].y;
        if(fin(x)!=fin(y)){
            mer(x,y);
        }
    }
    //for(int i=1;i<=n;i++) fin(i),cout<<fa[i]<<" ";
    //cout<<endl;
    for(int i=1;i<=n;i++) int k=fin(i);
    int faa=fa[1]; 
    for(int i=2;i<=n;i++) if(fa[i]!=faa){
        printf("0");return 0;
    } 
    
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        //cout<<"--------------------------"<<i<<"---------------------------"<<endl;
        memset(edge,0,sizeof edge);tot=0;
        int nc=bian[i].val;
        int st=i,ed;
        while(bian[i].val==nc){
            int k1=fin(bian[i].x);
            int k2=fin(bian[i].y);
            if(k1!=k2){
                //cout<<i<<" : "<<bian[i].x<<" "<<bian[i].y<<" : "<<k1<<" "<<k2<<endl;
            edge[++tot]=i;
            
            }
            i++;
        }
        i--;
        
        memcpy(ff,fa,sizeof fa);
        for(int j=1;j<=tot;j++){
            mer(bian[edge[j]].x,bian[edge[j]].y);
        }
        ///for(int j=1;j<=tot;j++) cout<<edge[j]<<" ";
        //cout<<endl;
        
        sort(edge+1,edge+tot+1,cmp2);
        
        for(int j=1;j<=tot;j++){
            //cout<<"***********"<<j<<"**********"<<endl;
            int now=fin(bian[edge[j]].x);
            memset(mem,0,sizeof mem);mems=0;
            int st=j,ed;
            while(fin(bian[edge[j]].x)==now){
                int k1=inf(bian[edge[j]].x);
                int k2=inf(bian[edge[j]].y);
                mem[++mems]=k1;
                mem[++mems]=k2;
                j++;
            }
            j--;
            ed=j;
            sort(mem+1,mem+mems+1);
            mems=unique(mem+1,mem+mems+1)-mem-1;
            
            /*cout<<"members "<<mems<<endl;
            for(int j=1;j<=mems;j++) cout<<mem[j]<<" ";
            cout<<endl;*/
            
            tr D,B;D.init();B.init();
            D.cnt=B.cnt=mems;
            for(int j=st;j<=ed;j++){
                //cout<<bian[edge[j]].x<<" && "<<bian[edge[j]].y<<endl;
                int x=li(inf(bian[edge[j]].x));
                int y=li(inf(bian[edge[j]].y));
                //cout<<" after li "<<x<<" && "<<y<<endl;
                D.f[x][x]+=1.0,D.f[y][y]+=1.0;
                B.f[x][y]+=1.0,B.f[y][x]+=1.0;
            }
            
            //D.op(); 
            //B.op();
            tr A=D-B;
            A.cnt--;
            ans=(ans*gauss(A))%mod;
        }
        
    }
    printf("%lld",ans);return 0;
}
最小生成树计数

错误点在于:

1.存的edge[i]才是编号,用的时候,for(j 1~tot) bian[edge[j].x 而不是bian[j].x

2.矩阵树,基尔霍夫矩阵要去掉一行一列

3.对于相同的边,

找出能加入的

再找出最终是同一个联通块里的。再在每个联通块里跑矩阵树。否则跑不出生成树。

而不是选择出了能加入的边,就直接矩阵树。

 

[国家集训队]middle(181行 3h跨零点)

#include<bits/stdc++.h>
using namespace std;
const int N=20000+10;
int n,m;
int a[N],num[N],mem;
int rt[N];
int x1,x2,x3,x4;
int li(int x){
    return lower_bound(num+1,num+mem+1,x)-num;
}
struct node{
    int sum,lmx,rmx;
    int lson,rson;
    bool ncl,ncr;
    #define s(x) t[x].sum
    #define ls(x) t[x].lson
    #define rs(x) t[x].rson
    #define lm(x) t[x].lmx
    #define rm(x) t[x].rmx
    #define cl(x) t[x].ncl
    #define cr(x) t[x].ncr
}t[N*40];
int tot;
vector<int>pos[N];
void pushup(int x){
    s(x)=s(ls(x))+s(rs(x));
    lm(x)=max(lm(ls(x)),s(ls(x))+lm(rs(x)));
    rm(x)=max(rm(rs(x)),s(rs(x))+rm(ls(x)));
}
int build(int l,int r){
    int id=++tot;
    if(l==r){
        if(li(a[l])<=1) s(id)=lm(id)=rm(id)=-1;
        else s(id)=lm(id)=rm(id)=1;
        return id;
    }
    int mid=l+r>>1;cl(id)=1;cr(id)=1;
    ls(id)=build(l,mid);rs(id)=build(mid+1,r);
    pushup(id);
    return id;
}
int upda(int x,int y,int l,int r,int to,int c,bool nc){
    //cout<<x<<" "<<y<<" : "<<l<<" and "<<r<<" : "<<to<<endl;
    if(!nc) {
    x=++tot;
    }
    if(l==r){
        s(x)=lm(x)=rm(x)=c;
        return x;
    }
    
    int mid=(l+r)>>1;
    if(to<=mid){
        if(!cr(x)) rs(x)=rs(y);
        if(!cl(x)){
            cl(x)=1;ls(x)=upda(x,ls(y),l,mid,to,c,0);
        }
        else{
            ls(x)=upda(ls(x),ls(y),l,mid,to,c,1);
        }
    }
    else{
        if(!cl(x)) ls(x)=ls(y);
        if(!cr(x)){
            cr(x)=1;rs(x)=upda(x,rs(y),mid+1,r,to,c,0);
        }
        else{
            rs(x)=upda(rs(x),rs(y),mid+1,r,to,c,1);
        }
    }
    pushup(x);
    return x;
}
int qs(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return s(x);
    }
    int mid=l+r>>1;int ret=0;
    if(L<=mid) ret+=qs(ls(x),l,mid,L,R);
    if(mid<R) ret+=qs(rs(x),mid+1,r,L,R);
    return ret;
}
node ql(int x,int l,int r,int L,int R){
    
    if(L<=l&&r<=R){
        return t[x];
    }
    int mid=l+r>>1;
    if(L<=mid&&mid<R){
        node ret;
        node le=ql(ls(x),l,mid,L,R);
        node ri=ql(rs(x),mid+1,r,L,R);
        ret.sum=le.sum+ri.sum;
        ret.lmx=max(le.lmx,le.sum+ri.lmx);
        return ret;
    }
    else if(L<=mid){
        return ql(ls(x),l,mid,L,R);
    }
    else {
        return ql(rs(x),mid+1,r,L,R);
    }
}
node qr(int x,int l,int r,int L,int R){
    //cout<<l<<" "<<r<<" goal "<<L<<" "<<R<<endl;
    if(L<=l&&r<=R){
        return t[x];
    }
    int mid=l+r>>1;
    if(L<=mid&&mid<R){
        //cout<<" double "<<endl;
        node ret;
        node le=qr(ls(x),l,mid,L,R);
        node ri=qr(rs(x),mid+1,r,L,R);
        ret.sum=le.sum+ri.sum;
        ret.rmx=max(ri.rmx,ri.sum+le.rmx);
        
        //cout<<"le "<<le.rmx<<" ri "<<ri.rmx<<" "<<ri.sum<<endl;
        //cout<<"ret "<<ret.sum<<" "<<ret.rmx<<endl;
        return ret;
    }
    else if(L<=mid){
        return qr(ls(x),l,mid,L,R);
    }
    else {
        return qr(rs(x),mid+1,r,L,R);
    }
}
bool che(int val){
    int sz=0;
    if(x2+1<=x3-1) sz=qs(rt[val],1,n,x2+1,x3-1);
    int sr=ql(rt[val],1,n,x3,x4).lmx;
    int sl=qr(rt[val],1,n,x1,x2).rmx;
//    cout<<"in binary "<<val<<endl;
    //cout<<sl<<" "<<sz<<" "<<sr<<endl;
    return (sl+sz+sr)>=0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),num[++mem]=a[i];
    sort(num+1,num+mem+1);
    mem=unique(num+1,num+mem+1)-num-1;
    for(int i=1;i<=n;i++){
        pos[li(a[i])].push_back(i);
    }
    rt[1]=build(1,n);
    for(int i=2;i<=mem;i++){
       //cout<<"building "<<i<<"--------------------------------"<<endl;
       for(int j=0;j<pos[i-1].size();j++){
           int go=pos[i-1][j];
           //cout<<" update "<<go<<endl;
            rt[i]=upda(rt[i],rt[i-1],1,n,go,-1,rt[i]>0);
       }
    }
    //cout<<"root "<<endl;
    //for(int i=1;i<=mem;i++) cout<<rt[i]<<' ';cout<<endl;
    scanf("%d",&m);
    int las=0;
    
    int ch[6];
    while(m--){
        scanf("%d%d%d%d",&x1,&x2,&x3,&x4);
        ch[1]=(x1+las)%n;
        ch[2]=(x2+las)%n;
        ch[3]=(x3+las)%n;
        ch[4]=(x4+las)%n;
        sort(ch+1,ch+4+1);
        x1=ch[1]+1,x2=ch[2]+1,x3=ch[3]+1,x4=ch[4]+1;
        int l=1,r=mem;
        int ans=0;
        while(l<=r){
            int mid=l+r>>1;
            if(che(mid)) ans=mid,l=mid+1;
            else r=mid-1;
        }
        las=num[ans];
        printf("%d\n",las);
    }
    return 0;
}
middle

其实题目不是很难想明白就是难写。

错误点在于:

1.审题不清楚。这个题中位数的定义是:奇数中间一个,偶数中间靠后的那个。二分的>=0 和 >0 的区别

2.手抖手抖手抖手抖打错了!!!!pushup把rm(ls)打成rs(ls)    -------------------直接出锅

(对拍过夜才找出来....)

[ZJOI2013]K大数查询(最后128行 5h跨零点)

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
const int N=50000+10;
int n,m;
struct node{
    int l,r;ll c;int id;int op;ll ans;
}q[N];
struct tr{
    int sum,ad;
}t[N*4];
int dp;
int tc;
vector<int>p[35];
int delepool[35];
void dele(int s){
    delepool[++dp]=s;
}
int nc(){
    int r=dp?delepool[dp--]:++tc;
    p[r].clear();
    return r;
}
int ans[N];
int tot;
void pushdown(int x,int l,int r){
    int mid=l+r>>1;
    t[x<<1].sum+=t[x].ad*(mid-l+1);
    t[x<<1|1].sum+=t[x].ad*(r-mid);
    t[x<<1].ad+=t[x].ad;
    t[x<<1|1].ad+=t[x].ad;
    t[x].ad=0;
}
void add(int x,int l,int r,int L,int R,int c){
    if(L<=l&&r<=R){
        t[x].sum+=c*(r-l+1);
        t[x].ad+=c;
        return;
    }
    pushdown(x,l,r);
    int mid=l+r>>1;
    if(L<=mid) add(x<<1,l,mid,L,R,c);
    if(mid<R) add(x<<1|1,mid+1,r,L,R,c);
    t[x].sum=t[x<<1].sum+t[x<<1|1].sum;
}
int query(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return t[x].sum;
    }
    pushdown(x,l,r);
    int mid=l+r>>1;
    int ret=0;
    if(L<=mid) ret+=query(x<<1,l,mid,L,R);
    if(mid<R) ret+=query(x<<1|1,mid+1,r,L,R);
    return ret;
}    

void div(int id,ll l,ll r){
    if(l==r){
        for(int i=0;i<p[id].size();i++){
            if(q[p[id][i]].op==2) q[p[id][i]].ans=l;
        }
        return;
    }
    ll mid=(ll)floor(((double)1.0*l+(double)1.0*r)/((double)2));

    int le=nc(),ri=nc();

    bool fl=false,fr=false;
    //le.clear();ri.clear();
    for(int i=0;i<p[id].size();i++){
        //cout<<" qu "<<p[id][i]<<" "<<q[p[id][i]].op<<endl;
        if(q[p[id][i]].op==1){
            if(q[p[id][i]].c<=mid) p[le].push_back(p[id][i]);
            else {
                p[ri].push_back(p[id][i]);
                add(1,1,n,q[p[id][i]].l,q[p[id][i]].r,1);
            }
        }
        else{
            int sum=query(1,1,n,q[p[id][i]].l,q[p[id][i]].r);
            //cout<<sum<<endl;
            if(sum>=q[p[id][i]].c){
                fr=true;
                p[ri].push_back(p[id][i]);
            }
            else
            {
                fl=true;
                q[p[id][i]].c-=sum;
                p[le].push_back(p[id][i]);
            }
        }
    }
    for(int i=0;i<p[id].size();i++){
        if(q[p[id][i]].op==1){
            if(q[p[id][i]].c>mid) {
                add(1,1,n,q[p[id][i]].l,q[p[id][i]].r,-1);
            }
        }
    }
    
    //cout<<p[le].size()<<"  and "<<fl<<" || "<<p[ri].size()<<" and "<<fr<<endl;
    if(p[le].size()&&fl)div(le,l,mid);
    dele(le);
    if(p[ri].size()&&fr)div(ri,mid+1,r);
    dele(ri);
}
signed main()
{
    scanf("%d%d",&n,&m);
    
    int st=nc();
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%lld",&q[i].op,&q[i].l,&q[i].r,&q[i].c);
        q[i].id=i;
        p[st].push_back(i);
    }
    //cout<<inf<<" "<<-inf<<endl;
    div(st,-n,n);
    for(int i=1;i<=m;i++){
        if(q[i].op==2){
            printf("%lld\n",q[i].ans);
        }
    }
    return 0;
}
K大数查询

错误点:

1.vector开太多MLE,TLE

2.集合中没有询问,可以剪枝。

3.vector垃圾回收(l==r)dele多删了一次。

4.蜜汁#define int long long才可以!?!?!?!??!!(tmd坑了3h)

 

[SCOI2014]方伯伯的商场之旅(2days 3遍程序)

采用gzz的做法

错误程序1:状态:f[i][a-b][0/1] 起初没有枚举x填多少,直接复制跳过了。

直接复制显然是错的。首先,[1]->[0],[0]->[0]就有两种情况。其次,填不同的x,可能都会到达[0]状态。

错误程序2:怎么处理1呢?加一维记录一个[0/1/2]代表x这一位填的数和a[p]的相对大小。相当于保证x填的范围。

虽然可以转移过来,但是最后统计答案会出锅。因为,处理完位置p,统计答案的时候,枚举x,

假设x>a[p],就会取f[1][a-b][0/1][2]这个位置,会把不是填x这个数,但是也满足>a[p]的x的贡献算进去的。

例如:

三进制下:
上限是6:2 0
5 : 1 2(会在位置2合并)
4 : 1 1(会在位置1合并)
当枚举p=2时,1,2都满足比a[p]=0大,
当枚举x=2时,会加上f[last][a-b=1][1/0],但是,最后一位填1也会贡献到这里。
然后,本来代价是1,就变成了1+1=2

正确程序:

外层枚举一个pos,再枚举一个x,钦定p这一位填x。最后统计就一点没有问题了。

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=70;
const int M=22;
const int fix=201;
const int up=402;
ll f[N][405][2];
ll g[N][405][2];
ll L,R;
int m;
ll ansl,ansr;
int a[N],cnt;
ll wrk(){
    ll ret=0;
    for(int p=1;p<=cnt;p++){
        //cout<<"----------------------------------  "<<p<<endl; 
       for(int x=0;x<m;x++){
        memset(f,0,sizeof f);
        memset(g,0,sizeof g);
        g[cnt+1][fix][1]=1;
        for(int i=cnt;i>=1;i--){
            //cout<<" i "<<" ---> "<<i<<endl;
            for(int j=0;j<=up;j++){
                    if(i==p){
                        if(x<a[i]){
                            if(g[i+1][j][0]) g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0];
                            if(g[i+1][j][1]) g[i][j][0]+=g[i+1][j][1],f[i][j][0]+=f[i+1][j][1];
                        }                        
                        else if(x==a[i]){
                            g[i][j][1]+=g[i+1][j][1],f[i][j][1]+=f[i+1][j][1];
                            g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0];
                        }
                        else{
                            g[i][j][0]+=g[i+1][j][0],f[i][j][0]+=f[i+1][j][0];
                        }
                        continue;
                    }
                    
                for(int k=0;k<m;k++){
                    
                    if(i>p){//before
                        if(j+k>up) continue;
                        
                        if(k<a[i]){
                            g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0];
                            g[i][j+k][0]+=g[i+1][j][1],f[i][j+k][0]+=f[i+1][j][1]+(i-p)*k*g[i+1][j][1];
                        }
                        else if(k==a[i]){
                            g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0];
                            g[i][j+k][1]+=g[i+1][j][1],f[i][j+k][1]+=f[i+1][j][1]+(i-p)*k*g[i+1][j][1];
                        }
                        else{
                            g[i][j+k][0]+=g[i+1][j][0],f[i][j+k][0]+=f[i+1][j][0]+(i-p)*k*g[i+1][j][0];
                        }
                    }
                    else{//after 
                    //if(p==1)//cout<<" oh shit owierhffhr "<<endl;
                        if(j-k<0) continue;
                    
                    
                        if(k<a[i]){
                            f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0];
                            f[i][j-k][0]+=f[i+1][j][1]+g[i+1][j][1]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][1];
                        }
                        else if(k==a[i]){
                            f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0];
                            f[i][j-k][1]+=f[i+1][j][1]+g[i+1][j][1]*(p-i)*k,g[i][j-k][1]+=g[i+1][j][1];
                        }
                        else{
                            f[i][j-k][0]+=f[i+1][j][0]+g[i+1][j][0]*(p-i)*k,g[i][j-k][0]+=g[i+1][j][0];
                        }
                      
                    
                    }
                    //if(i!=p){
                    
                    /*if(j-fix>=0&&j-fix<=3){
                    cout<<j<<" and "<<k<<endl;
                    cout<<" f "<<f[i][j+k][0]<<" "<<f[i][j+k][1]<<endl;
                    cout<<" g "<<g[i][j+k][0]<<" "<<g[i][j+k][1]<<endl;
                    }}
                    else{
                        if(j-fix>=0&&j-fix<=3){
                            //cout<<j<<" and "<<k<<endl;
                            //cout<<" f : q1 "<<f[i][j][0]<<" "<<f[i][j][1]<<" q2 "<<f[i][j][0][1]<<" "<<f[i][j][1][1]<<" q3 "<<f[i][j][0][2]<<" "<<f[i][j][1][2]<<endl;
                            //cout<<" g : q1 "<<g[i][j][0]<<" "<<g[i][j][1<<" q2 "<<g[i][j][0][1]<<" "<<g[i][j][1][1]<<" q3 "<<g[i][j][0][2]<<" "<<g[i][j][1][2]<<endl;
                        }
                    }*/
                }
            }
        }
        
            //cout<<" ins "<<x<<" ******************* "<<endl;
            for(int j=0;j<=up;j++){
                //if(j-fix>=0&&j-fix<=3) 
                //  cout<<" jj "<<j<<endl;
                
                    if((fix-x<=j)&&(j<x+fix)){
                        ret+=f[1][j][0]+f[1][j][1];
                        
                    }
            
                //if(j-fix>=0&&j-fix<=3) 
                //  cout<<" ret "<<ret<<endl;
            }
        }
        //cout<<ret<<endl;
        
    }    
    return ret;
}
int main(){
    scanf("%lld%lld",&L,&R);
    scanf("%d",&m);
    L--;
    cnt=0;
    while(L){
        a[++cnt]=L%m;
        L/=m;
    }
    if(cnt==0){
        ansl=0;
    }
    else{
        ansl=wrk();
    }
    
    cnt=0;
    while(R){
        a[++cnt]=R%m;
        R/=m;
    }
    //cout<<" R "<<cnt<<endl;
    //for(int i=cnt;i>=1;i--)cout<<a[i]<<" ";cout<<endl;
    ansr=wrk();
    
    //cout<<ansr<<" "<<ansl<<endl;
    printf("%lld",ansr-ansl);
}
方伯伯的商场之旅

 

 

[CQOI2016]手机号码

比较麻烦的数位dp,其实就花了大概50min

目前最长代码331行。。。。。记录一下而已。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=13;
ll l,r;
ll f[N][2][10][10][2][2][2];
int num[N],cnt;
bool is=false;
ll wrk(){
    memset(f,0,sizeof f);
    for(int i=0;i<=num[cnt]*10+num[cnt-1];i++){
        int y=i%10,x=i/10;
        if(y==num[cnt-1]&&x==num[cnt]){
            f[cnt-1][1][x][y][0][(x==4)||(y==4)][(x==8)||(y==8)]++;
        }
        else{
            f[cnt-1][0][x][y][0][(x==4)||(y==4)][(x==8)||(y==8)]++;
        }
    }
    for(int i=cnt-2;i>=1;i--){
        for(int j=0;j<=9;j++){
            for(int k=0;k<=9;k++){
                for(int p=0;p<=9;p++){
                    if(p<num[i]){
                        if(p==4){
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+    f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1];
                            
                                f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+    f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            
                        }
                        else if(p==8){
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+    f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1]+f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0];
                            
                                f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+    f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1]+f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            
                        }
                        else{
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][0]+=f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][0][j][k][1][1][1]+    f[i+1][1][j][k][0][1][1]+f[i+1][0][j][k][0][1][1];
                            
                                f[i][0][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][0][j][k][1][1][0]+    f[i+1][1][j][k][0][1][0]+f[i+1][0][j][k][0][1][0];
                            
                                f[i][0][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][0][j][k][1][0][1]+    f[i+1][1][j][k][0][0][1]+f[i+1][0][j][k][0][0][1];
                            
                                f[i][0][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+f[i+1][0][j][k][1][0][0]+    f[i+1][1][j][k][0][0][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                        }
                    }
                    else if(p==num[i]){
                        if(p==4){
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0];
                            
                            f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][0][1];
                            
                            f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][0][1];
                            
                            f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][1][j][k][1][0][0];
                            
                            f[i][1][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0]+f[i+1][1][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]+    f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1];
                               
                                f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][0][1]+    f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][0][1];
                                
                                f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0];
                            
                                f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+f[i+1][1][j][k][1][0][0]+    f[i+1][1][j][k][0][1][0]+f[i+1][1][j][k][0][0][0];
                                
                            }
                        }
                        else if(p==8){
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0];
                            
                            f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][1][0];
                            
                            f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][1][0];
                            
                            f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][1][j][k][1][0][0];
                            
                            f[i][1][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1]+f[i+1][1][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]+    f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0];
                               
                                f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+f[i+1][1][j][k][1][1][0]+    f[i+1][1][j][k][0][1][1]+f[i+1][1][j][k][0][1][0];
                                
                                f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0];
                            
                                f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+f[i+1][1][j][k][1][0][0]+    f[i+1][1][j][k][0][0][1]+f[i+1][1][j][k][0][0][0];
                            
                            }
                        }
                        else{
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][0]+=f[i+1][0][j][k][0][0][0];
                            
                            
                            f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1];
                            
                            f[i][1][k][p][0][1][1]+=f[i+1][1][j][k][0][1][1];
                            
                            f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0];
                            
                            f[i][1][k][p][0][1][0]+=f[i+1][1][j][k][0][1][0];
                            
                            f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1];
                            
                            f[i][1][k][p][0][0][1]+=f[i+1][1][j][k][0][0][1];
                            
                            f[i][1][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0];
                            
                            f[i][1][k][p][0][0][0]+=f[i+1][1][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+    f[i+1][0][j][k][0][1][1];
                            
                                f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+    f[i+1][0][j][k][0][1][0];
                            
                                f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+    f[i+1][0][j][k][0][0][1];
                            
                                f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][0][0];
                            
                            
                                f[i][1][k][p][1][1][1]+=f[i+1][1][j][k][1][1][1]+    f[i+1][1][j][k][0][1][1];
                            
                                f[i][1][k][p][1][1][0]+=f[i+1][1][j][k][1][1][0]+    f[i+1][1][j][k][0][1][0];
                            
                                f[i][1][k][p][1][0][1]+=f[i+1][1][j][k][1][0][1]+    f[i+1][1][j][k][0][0][1];
                            
                                f[i][1][k][p][1][0][0]+=f[i+1][1][j][k][1][0][0]+    f[i+1][1][j][k][0][0][0];
                            
                            }
                            
                        }
                    }
                    else{// p>num[i]
                        
                        if(p==4){
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][0][1]+    f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][0][1];
                               
                                f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][1][0]+f[i+1][0][j][k][0][0][0];
                            
                            }
                        }
                        else if(p==8){
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+f[i+1][0][j][k][1][1][0]+    f[i+1][0][j][k][0][1][1]+f[i+1][0][j][k][0][1][0];
                               
                                f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][0][1]+f[i+1][0][j][k][0][0][0];
                            
                            }
                        }
                        else{
                            
                            if(k!=p||p!=j||j!=k){
                            
                            f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1];
                            
                            f[i][0][k][p][0][1][1]+=f[i+1][0][j][k][0][1][1];
                            
                            f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0];
                            
                            f[i][0][k][p][0][1][0]+=f[i+1][0][j][k][0][1][0];
                            
                            f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1];
                            
                            f[i][0][k][p][0][0][1]+=f[i+1][0][j][k][0][0][1];
                            
                            f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0];
                            
                            f[i][0][k][p][0][0][0]+=f[i+1][0][j][k][0][0][0];
                            
                            }
                            else if (k==p&&p==j){
                                f[i][0][k][p][1][1][1]+=f[i+1][0][j][k][1][1][1]+    f[i+1][0][j][k][0][1][1];
                            
                                f[i][0][k][p][1][1][0]+=f[i+1][0][j][k][1][1][0]+    f[i+1][0][j][k][0][1][0];
                            
                                f[i][0][k][p][1][0][1]+=f[i+1][0][j][k][1][0][1]+    f[i+1][0][j][k][0][0][1];
                            
                                f[i][0][k][p][1][0][0]+=f[i+1][0][j][k][1][0][0]+    f[i+1][0][j][k][0][0][0];
                            
                            }
                            
                        }
                        
                    }
                }
            }
        }
    }
    
    ll ret=0;
    for(int j=0;j<=9;j++)
     for(int k=0;k<=9;k++){
         ret+=f[1][0][j][k][1][1][0]+f[1][1][j][k][1][1][0]+f[1][0][j][k][1][0][1]+f[1][1][j][k][1][0][1]+f[1][0][j][k][1][0][0]+f[1][1][j][k][1][0][0];
     }
    return ret;
}
int main()
{
    scanf("%lld%lld",&l,&r);
    
    if(l!=1e10) l--;
    else is=true;
    
    while(l){
        num[++cnt]=l%10;l/=10;
    }
    ll ans1=wrk();
    
    cnt=0;
    while(r){
        num[++cnt]=r%10;r/=10;
    }
    ll ans2=wrk();
    
    printf("%lld",ans2-ans1+is);
    return 0;
}
[CQOI2016]手机号码

 

[NOI2005]维护数列(真·目前最长7h)

平衡树观止码农题。3h打码,4h调试。。。。

(其实对于基础的题目,不太清楚打标记什么的,也可以直接看题解。)

[NOI2005]维护数列——平衡树观止

#include<bits/stdc++.h>
#define rs t[x].ch[1]
#define ls t[x].ch[0]
#define numb ch-'0'
#define ri register int
#define il inline
using namespace std;
typedef long long ll;
const int N=500000+5;
const ll inf=(1LL*1<<61);
char ch;
il void rdint(int &x){
    x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
il void rdll(ll &x){
    x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
struct node{
    int ch[2],fa;
    ll rm,lm,sum,ans;
    int rev;
    ll chan;
    ll val;
    int sz;
    void init(int f,ll v){
        fa=f,val=v;rm=v;lm=v,ans=v,sum=v;
        rev=0,chan=inf;
        sz=1;
    }
}t[N];
il ll Max(ll a,ll b){
    return a>b?a:b;
}
int dc,dp[N],pc;
int n,m,rt;
ll st[N];
il int nc(){
    int r=dc?dp[dc--]:++pc;
    memset(t+r,0,sizeof (node));return r;
}
il void pushup(int x){
    t[x].sum=t[t[x].ch[0]].sum+t[t[x].ch[1]].sum+t[x].val;
    t[x].rm=Max(t[t[x].ch[1]].rm,Max(t[t[x].ch[1]].sum+t[x].val,t[t[x].ch[1]].sum+t[x].val+t[t[x].ch[0]].rm));
    t[x].lm=Max(t[t[x].ch[0]].lm,Max(t[t[x].ch[0]].sum+t[x].val,t[t[x].ch[0]].sum+t[x].val+t[t[x].ch[1]].lm));
    t[x].ans=Max(t[x].lm,t[x].rm);
    t[x].ans=Max(t[x].ans,Max(t[t[x].ch[0]].rm+t[x].val+t[t[x].ch[1]].lm,Max(t[t[x].ch[0]].rm+t[x].val,t[x].val+t[t[x].ch[1]].lm)));
    t[x].ans=Max(t[x].ans,Max(t[t[x].ch[0]].ans,t[t[x].ch[1]].ans));
    t[x].ans=Max(t[x].ans,t[x].val);//bug 2
    t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+1;
}
il void pushdown(int x){
    if(t[x].chan!=inf){
        if(ls){
        t[ls].chan=t[x].chan;
        t[ls].val=t[x].chan;
        t[ls].sum=t[ls].val*t[ls].sz;
        t[ls].rm=t[ls].lm=t[ls].ans=t[ls].val>0?t[ls].sum:t[ls].val;
        }
        if(rs){
        t[rs].chan=t[x].chan;
        t[rs].val=t[x].chan;
        t[rs].sum=t[rs].val*t[rs].sz;
        t[rs].rm=t[rs].lm=t[rs].ans=t[rs].val>0?t[rs].sum:t[rs].val;
        }
        t[x].chan=inf;
    }
    if(t[x].rev){
        if(ls&&t[ls].val!=-inf){
        t[ls].rev^=1;
        swap(t[ls].lm,t[ls].rm);//bug1
        }
        if(rs&&t[rs].val!=-inf){
        t[rs].rev^=1;
        swap(t[rs].lm,t[rs].rm);//bug1
        }
        swap(ls,rs);
        t[x].rev=0;
    }
}
il void rotate(int x){
    int y=t[x].fa,d=t[y].ch[1]==x;
    t[t[y].ch[d]=t[x].ch[!d]].fa=y;
    t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x;
    t[t[x].ch[!d]=y].fa=x;
    pushup(y);
}
il void splay1(int x,int f){
    while(t[x].fa!=f){
        int y=t[x].fa,z=t[y].fa;
        if(z!=f){
            rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x);
        }
        rotate(x);
    }
    pushup(x);
    if(f==0) rt=x;
}
il int kth(int k){
    int x=rt;
    while(1){
        pushdown(x);
        int d=k-t[t[x].ch[0]].sz;
        if(d<=0) x=t[x].ch[0];
        else if(d==1) return x;
        else{
            k=d-1;
            x=t[x].ch[1];
        }
    }
}
int newrt;
il void splay2(int x,int f){
    while(t[x].fa!=f){
        int y=t[x].fa,z=t[y].fa;
        if(z!=f){
            rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x);
        }
        rotate(x);
    }
    pushup(x);
    if(f==0) newrt=x;
}
il void build(ll v){
    if(!newrt){
        newrt=nc();
        t[newrt].init(0,v);
        return;
    }
    int x=newrt;
    while(1){
        if(!t[x].ch[1]){
            t[x].ch[1]=nc();
            t[t[x].ch[1]].init(x,v);
            x=t[x].ch[1];
            break;
        }
        x=t[x].ch[1];
    }
    splay2(x,0);
}
il int pre(int l,int r,int f){
    if(l>r){
        return 0;
    }
    int mid=(l+r)>>1;
    int x=nc();
    t[x].init(f,st[mid]);
    t[x].ch[0]=pre(l,mid-1,x);
    t[x].ch[1]=pre(mid+1,r,x);
    pushup(x);
    return x;
}
il void ins(int pos,int tot){
    newrt=0;
    for(ri i=1;i<=tot;i++){
        rdll(st[i]);
    }
    newrt=pre(1,tot,0);
    int x=kth(pos+1);
    int y=kth(pos+2);
    splay1(x,0);
    splay1(y,x);
    t[y].ch[0]=newrt;
    t[newrt].fa=y;
    pushup(y);
    pushup(x);
}
il void del(int x){
    if(t[x].ch[0]) del(t[x].ch[0]);
    dp[++dc]=x;
    if(t[x].ch[1]) del(t[x].ch[1]);
}
il void remove(int pos,int tot){
    int l=kth(pos);
    int r=kth(pos+tot+1);
    splay1(l,0);
    splay1(r,l);
    del(t[r].ch[0]);
    t[r].ch[0]=0;
    pushup(r);
    pushup(l);
}
il void upda(int pos,int tot,ll c){
    int l=kth(pos);
    int r=kth(pos+tot+1);
    splay1(l,0);
    splay1(r,l);
    
    int x=t[r].ch[0];
    t[x].chan=c;
    t[x].val=c;
    t[x].sum=t[x].val*t[x].sz;
    t[x].rm=t[x].lm=t[x].ans=t[x].val>0?t[x].sum:t[x].val;
    
    pushup(r);
    pushup(l);
}
il void reverse(int pos,int tot){
    int l=kth(pos);
    int r=kth(pos+tot+1);
    splay1(l,0);
    splay1(r,l);
    
    int x=t[r].ch[0];
    t[x].rev^=1;
    swap(t[x].lm,t[x].rm);    
    
    pushup(r);
    pushup(l);
}
il ll qs(int pos,int tot){
    int l=kth(pos);
    int r=kth(pos+tot+1);
    splay1(l,0);
    splay1(r,l);
    
    int x=t[r].ch[0];
    int ret=t[x].sum;
    pushdown(x);//bug 3
    splay1(x,0);
    return ret;
}

int main()
{
    t[0].lm=t[0].rm=t[0].ans=-inf;//warning warning warning !!! 
    t[0].sz=0;t[0].sum=0;
    scanf("%d%d",&n,&m);
    st[1]=-inf;
    for(int i=2;i<=n+1;i++){
        rdll(st[i]);
    }
    st[n+2]=-inf;
    
    rt=pre(1,n+2,0);
    char lp[20];
    int pos,tot;
    ll c;
    int cnt=0;
    for(ri i=1;i<=m;i++){
        ch=getchar();
        while(ch>'Z'||ch<'A')ch=getchar();
        for(cnt=0;(ch=='-')||(ch<='Z'&&ch>='A');ch=getchar())lp[++cnt]=ch;
        if(lp[1]=='I'){
            rdint(pos),rdint(tot);
            if(tot==0) continue;
            ins(pos,tot);
        }
        else if(lp[1]=='D'){
            rdint(pos),rdint(tot);
            if(tot==0) continue;
            remove(pos,tot);
        }
        else if(lp[1]=='M'&&lp[3]=='K'){
            rdint(pos),rdint(tot);rdll(c);
            if(tot==0) continue;
            upda(pos,tot,c);
        }
        else if(lp[1]=='M'&&lp[3]=='X'){
            printf("%lld\n",t[rt].ans);
        }
        else if(lp[1]=='G'){
            rdint(pos),rdint(tot);
            if(tot==0) printf("0\n");
            else printf("%lld\n",qs(pos,tot));
        }
        else if(lp[1]=='R'){
            rdint(pos),rdint(tot);
            if(tot==0) continue;
            reverse(pos,tot);
        }
    }
    return 0;
}
维护数列

 

 

相逢是问候(4h)

漂亮的数学+数据结构+预处理综合题。

[六省联考2017]相逢是问候——欧拉公式+线段树

#include<bits/stdc++.h>
#define numb (ch^'0')
#define mid ((l+r)>>1)
using namespace std;
typedef long long ll;
const int N=50000+5;
ll n,m,p,c;
void rd(ll &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=numb;isdigit(ch=getchar());x=(x<<1)+(x<<3)+numb);
}
ll a[N];
int b[N];
int up;
int phi[N];
ll ci[N];
int ouler(ll x){
    int ret=x;
    for(int i=2;i*i<=x;i++){
        //cout<<i<<" "<<x<<endl;
        if(x%i==0){
            ret=ret/i*(i-1);
            while(x%i==0) x/=i;
        }
    }
    if(x>1) ret=ret/x*(x-1);
    return ret;
}
ll num[N][35];
ll qm(ll x,ll y,ll mod){
    ll ret=1%mod;
    while(y){
        if(y&1) (ret*=x)%=mod;
        (x*=x)%=mod;
        y>>=1;
    }
    return ret;
}
ll mi1[10005][35];
ll mi2[10005][35];
ll tim(int id,int dep,int lim){
    if(dep==lim){
        return a[id]<phi[dep]?a[id]:a[id]%phi[dep]+phi[dep];
    }
    ll tmp=tim(id,dep+1,lim);
    ll ret=0;
    if(c==1){
        ret=1;
        if(ret>=phi[dep]) ret=ret%phi[dep]+phi[dep];
    }else if(c==0){
        ret=1;
        if(ret>=phi[dep]) ret=ret%phi[dep]+phi[dep];
    }else{
        if(tmp>50) ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep])+phi[dep];
        else if(ci[tmp]<0||ci[tmp]>=phi[dep]) ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep])+phi[dep];
        else ret=(mi2[tmp/10000][dep]*mi1[tmp%10000][dep]%phi[dep]);
    }
    return ret;
}

struct node{
    ll mx,sum;
}t[N<<2];
void pushup(int x){
    t[x].sum=(t[x<<1].sum+t[x<<1|1].sum)%p;
    t[x].mx=max(t[x<<1].mx,t[x<<1|1].mx);
}
void build(int x,int l,int r){
    if(l==r){
        t[x].sum=a[l];
        t[x].mx=up;return;
    }
    build(x<<1,l,mid);build(x<<1|1,mid+1,r);
    pushup(x);
}
void chan(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        if(l==r) {
            t[x].mx=max(t[x].mx-1,(ll)0);
            t[x].sum=num[l][up-t[x].mx];
            return;
        }
        else{
            if(t[x<<1].mx>0) chan(x<<1,l,mid,L,R);
            if(t[x<<1|1].mx>0) chan(x<<1|1,mid+1,r,L,R);
            pushup(x);
            return;
        }
    }
    else{
        if(L<=mid) chan(x<<1,l,mid,L,R);
        if(mid<R) chan(x<<1|1,mid+1,r,L,R);
        pushup(x);
        return;
    }
}
ll query(int x,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return t[x].sum;
    }
    ll ret=0;
    if(L<=mid) (ret+=query(x<<1,l,mid,L,R))%=p;
    if(mid<R) (ret+=query(x<<1|1,mid+1,r,L,R))%=p;
    return ret;
}
int main(){
    //freopen("1.in","r",stdin);
    //freopen("mine.out","w",stdout);
    rd(n);rd(m);rd(p);rd(c);
    ci[0]=1;
    for(int i=1;i<=50;i++){
        ci[i]=ci[i-1]*c;
        if(ci[i]>2e9) ci[i]=-1;
        if(ci[i]<0) ci[i]=-1;
    }
    
    int tmp=p;
    phi[0]=p;
    while(tmp!=1){
        up++;
        //if(up<15)cout<<up<<" "<<tmp<<endl;
        phi[up]=ouler(tmp);
        tmp=phi[up];
    }
    up++;phi[up]=tmp;
    
    for(int j=0;j<=up;j++){
        //cout<<j<<endl;
        mi1[0][j]=1%phi[j];
        ll t=qm(c,10000,phi[j]);
        mi2[0][j]=1%phi[j];
        for(int i=1;i<=10000;i++){
            //cout<<i<<endl;
            mi1[i][j]=qm(c,i,phi[j]);
            mi2[i][j]=qm(t,i,phi[j]);
        }
    }


    
    
    //cout<<" up "<<up<<endl;
    for(int i=1;i<=n;i++) rd(a[i]);
    for(int i=1;i<=n;i++) {
        //cout<<" ii "<<i<<" ---------------"<<a[i]<<endl;
        //rd(a[i]);
        num[i][0]=a[i];
        for(int j=1;j<=up;j++){
            num[i][j]=tim(i,0,j)%p;
            //cout<<j<<" : "<<num[i][j]<<endl;
        }
    }
    
    //cout<<" num "<<num[8][0]<<" "<<num[8][1]<<" "<<num[8][2]<<" "<<num[8][3]<<endl;
    
    build(1,1,n);
    ll op,l,r;
    while(m--){
        rd(op);rd(l);rd(r);
        if(op){
            printf("%lld\n",query(1,1,n,l,r));
        }
        else{
            chan(1,1,n,l,r);
        }
    }
    return 0;
}
相逢是问候

 

 

列队(Splay)(2.5h)

平衡树蒟蒻,敲了半天。

其实思路很简单,就是把许多个人合并成一个区间。必要的时候再拆开。(是不是和这个题的动态开点线段树有异曲同工之妙?)

出错点:

1.pushup把哨兵sz变成了1:pushup要特判x!=0(比较保险)

2.fa和son的边一定要成对一起添加!!t[t[y].ch[0]=t[x].ch[0]].fa=y 压行的话不容易漏。

3.对于一列的情况,可能删除之后整个树空了。但是如果直接找的话,因为哨兵0有奇奇怪怪的左右儿子和father,所以,一路上会把0的sz变成1,并且访问到奇奇怪怪的点23333

那就特判如果没有根的话,那就直接建立即可。

#include<bits/stdc++.h>
#define reg register int
#define il inline
using namespace std;
typedef long long ll;
const int N=300000+5;
struct node{
    int ch[2];
    int sz;
    int L,R;
    int fa;
    ll val;
}t[N*15];
int tot;
void rd(int &x){
    char ch;x=0;
    while(!isdigit(ch=getchar()));
    for(x=ch^'0';isdigit(ch=getchar());x=x*10+(ch^'0'));
}
int rt[N];
int now;
int n,m,q;
void pushup(int x){
    if(x)
    t[x].sz=t[t[x].ch[0]].sz+t[t[x].ch[1]].sz+t[x].R-t[x].L+1;
}
void rotate(int x){
    int y=t[x].fa,d=(t[y].ch[1]==x);
    t[t[y].ch[d]=t[x].ch[!d]].fa=y;
    t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x;
    t[t[x].ch[!d]=y].fa=x;
    pushup(y);
}
void splay(int x,int f){
    while(t[x].fa!=f){
        int y=t[x].fa,z=t[y].fa;
        if(z!=f){
            rotate((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x);
        }
        rotate(x);
    }
    pushup(x);
    if(f==0) rt[now]=x;
}
ll get(int pos){
    if(now==n+1){
        return (ll)pos*m;
    }
    return (ll)(now-1)*m+pos;
}
void ins(int x,ll c){
    if(x==0){
        ++tot;
        t[tot].fa=0;
        t[tot].val=c;
        t[tot].L=t[tot].R=0;
        pushup(tot);
        rt[now]=tot;
    }
    else{
        while(t[x].ch[1]) t[x].sz++,x=t[x].ch[1];
    
        ++tot;
        t[x].ch[1]=tot;
        t[tot].fa=x;
        t[tot].L=t[tot].R=0;t[tot].val=c;
        t[tot].sz=1;
        pushup(x);    
    //        cout<<x<<": "<<" sz "<<t[x].sz<<" "<<t[x].fa<<" "<<t[t[x].fa].ch[0]<<endl;
        splay(tot,0);
    //    cout<<t[rt[now]].sz<<" "<<endl;
        int tmp=rt[now];
    //    while(t[tmp].ch[0]) tmp=t[tmp].ch[0],cout<<"233 "<<tmp<<endl;
    }
}
ll query(int x,int k){//and dele
//    cout<<"--------------------------------- query "<<x<<" "<<k<<endl;
    int d=k-t[t[x].ch[0]].sz;
    if(d<=0) return query(t[x].ch[0],k);
    else if(t[x].R-t[x].L+1<d) return query(t[x].ch[1],d-(t[x].R-t[x].L+1));
    else{//find position
//        cout<<" find "<<x<<endl;
        ll ret=0;
        if(t[x].R>t[x].L){
            if(d>1){
                ++tot;
                t[tot].L=t[x].L;t[tot].R=t[x].L+d-2;
                t[t[tot].ch[0]=t[x].ch[0]].fa=tot;
                t[t[x].ch[0]=tot].fa=x;
                pushup(tot);
            }
            if(d<t[x].R-t[x].L+1){
                ++tot;
                t[tot].L=t[x].L+d;t[tot].R=t[x].R;
                t[t[tot].ch[1]=t[x].ch[1]].fa=tot;
                t[t[x].ch[1]=tot].fa=x;
                pushup(tot);
            }
            t[x].val=get(t[x].L+d-1);
            t[x].L=t[x].R=0;
        }else if(t[x].R){
        //    cout<<" here "<<endl;
            t[x].val=get(t[x].R);
            t[x].L=t[x].R=0;
        //    cout<<"val "<<t[x].val<<endl;
        }
        pushup(x);
        
        ret=t[x].val;
        
        splay(x,0);
        
        
        
        int son=t[x].ch[1];
        if(!son){
            t[rt[now]=t[x].ch[0]].fa=0;
            pushup(rt[now]);//cout<<"000 "<<t[0].sz<<endl;
        }
        else{
            while(t[son].ch[0]) son=t[son].ch[0];
            splay(son,rt[now]);
            
            t[t[son].ch[0]=t[x].ch[0]].fa=son;
            t[son].fa=0;
            pushup(son);
            rt[now]=son;
//            cout<<rt[now]<<" : "<<t[rt[now]].L<<" "<<t[rt[now]].R<<" "<<t[rt[now]].val<<" "<<t[rt[now]].ch[0]<<" "<<t[rt[now]].ch[1]<<" "<<t[rt[now]].sz<<endl;
        }
        
        return ret;
    }
}
void op(int x){
    cout<<" from "<<t[x].fa<<endl;
    if(t[x].ch[0]) op(t[x].ch[0]);
    cout<<" back to "<<x<<" "<<endl;
    cout<<x<<endl;
    cout<<" go right "<<x<<" "<<endl;
    if(t[x].ch[1]) op(t[x].ch[1]);
}
int main(){
    //freopen("data.in","r",stdin);
    //freopen("ut","w",stdout);
    rd(n);rd(m);rd(q);
    int x,y;
    for(reg i=1;i<=n;++i){
        rt[i]=++tot;
        t[tot].L=1,t[tot].R=m-1;
        t[tot].sz=m-1;
        t[tot].fa=0;
    }
    rt[n+1]=++tot;
    t[tot].L=1,t[tot].R=n;
    t[tot].sz=n;
    while(q--){
        rd(x);rd(y);
        ll id=0;
        if(y==m) now=n+1,id=query(rt[now],x);
        else now=x,id=query(rt[now],y);
        //cout<<" zero "<<t[0].sz<<endl;    
        
        printf("%lld\n",id);
//        cout<<" over "<<rt[n+1]<<endl;
//        op(rt[n+1]);
        now=n+1;
        ins(rt[now],id);
        
//        //cout<<" ins "<<endl;
//        for(int i=1;i<=n+1;++i){
//            cout<<i<<" : "<<rt[i]<<" : "<<t[rt[i]].sz<<" "<<t[rt[i]].L<<" "<<t[rt[i]].R<<endl;
//        }
//        
        if(y!=m){
            now=n+1;
            id=query(rt[now],x);
            now=x;
            ins(rt[now],id);
        }
//        cout<<" after "<<endl;
//        for(int i=1;i<=n+1;++i){
//            cout<<i<<" : "<<rt[i]<<" : "<<t[rt[i]].sz<<" "<<t[rt[i]].L<<" "<<t[rt[i]].R<<endl;
//        }
//        cout<<" fa "<<t[rt[n+1]].fa<<endl;
//        op(rt[n+1]);
    }
    return 0;
}
列队

 

无限之环(3h)

网络流神题。其实也不算太神。如果想到了网络流可能建图也不是什么很难想到的。

出错点:

1.数组开小了。。。。has[4],四位二进制数,少开一位。。。(这个导致开O2之后超级厌氧,全部输出-1WA掉,一定程度上转移了查错重心。。。)

2.提取四位二进制数的时候,习惯性地写成了while(tmp) has[++tot]=tmp%2,tmp>>=1;然鹅,最高位是0的话,没有提取完4位就break了。而且has没有memset,高位就存上了之前可能的1.。。。。导致WA死。。

其实开始找规律一点没错。。。。但是由于while高位0的锅,以为找错了,,,最后还打了暴力判断。。。。

规律版(240行):

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=2000+2;
const int inf=0x3f3f3f3f;
int n,m,s,t;
struct node{
    int nxt,to;
    int w,v;
}e[(5*N+4*N+N*6)*2];
int hd[5*N],cnt=1;
void add(int x,int y,int w,int v){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    e[cnt].w=w;
    e[cnt].v=v;
    hd[x]=cnt;
    
    e[++cnt].nxt=hd[y];
    e[cnt].to=x;
    e[cnt].w=0;
    e[cnt].v=-v;
    hd[y]=cnt;
}
int incf[5*N],dis[5*N];
int pre[5*N];
bool vis[5*N];
queue<int>q;
bool spfa(){
    while(!q.empty()) q.pop();
    memset(vis,0,sizeof vis);
    memset(dis,inf,sizeof dis);
    dis[s]=0;
    incf[s]=inf;
    pre[s]=0;
    q.push(s);
    while(!q.empty()){
        int x=q.front();q.pop();
        vis[x]=0;
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(e[i].w&&dis[y]>dis[x]+e[i].v){
                dis[y]=dis[x]+e[i].v;
                pre[y]=i;
                incf[y]=min(e[i].w,incf[x]);
                if(!vis[y]){
                    vis[y]=1;
                    q.push(y);
                }
            }    
        }
    }
    if(dis[t]==inf) return false;
    return true;
}
int ans,maxflow;
void upda(){
    int x=t;
    while(pre[x]){
        e[pre[x]].w-=incf[t];
        e[pre[x]^1].w+=incf[t];
        x=e[pre[x]^1].to;
    }
    ans+=incf[t]*dis[t];
    maxflow+=incf[t];
    //cout<<" ans "<<ans<<" "<<maxflow<<endl;
}
int has[10],tot;
int mp[N][N];
int sz[N];
int num(int x,int y,int k){//5 is itself
    return ((x-1)*m+y-1)*5+k;
}
int main(){
    rd(n);rd(m);
    s=0,t=n*m*5+1;
    for(reg i=1;i<=16;++i){
        sz[i]=sz[i>>1]+(i&1);
    }
    int le=0,ri=0;
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=m;++j){
            rd(mp[i][j]);
            if((i+j)%2==0) add(s,num(i,j,5),sz[mp[i][j]],0),le+=sz[mp[i][j]];
            else add(num(i,j,5),t,sz[mp[i][j]],0),ri+=sz[mp[i][j]];
        }
    }
    if(le!=ri){
        printf("-1");return 0;
    }
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=m;++j){
            for(reg l=1;l<=4;++l){
                has[l]=(mp[i][j]>>(l-1))&1;
            }
            int now=num(i,j,5);
            tot=sz[mp[i][j]];
            if((i+j)%2==0){
                switch(tot){
                    case 0:{
                        break;
                    }
                    case 1:{
                        int pos=0;
                        //cout<<" find "<<mp[i][j]<<" :: "<<has[1]<<" "<<has[2]<<" "<<has[3]<<" "<<has[4]<<endl;
                        for(reg l=1;l<=4;++l) if(has[l]) {
                            pos=l;
                        }
                        add(now,num(i,j,pos),1,0);
                        add(now,num(i,j,pos%4+1),1,1);
                        add(now,num(i,j,pos==1?4:pos-1),1,1);
                        add(now,num(i,j,(pos+2<=4)?pos+2:pos-2),1,2);
                        break;
                    }
                    case 2:{
                        if(mp[i][j]==5||mp[i][j]==10){
//    cout<<" dkfjdf "<<endl;
                            for(reg l=1;l<=4;++l){
                                if(has[l]) add(now,num(i,j,l),1,0);
                            }
                        }else{
                            for(reg l=1;l<=4;++l){
                                if(has[l]) {
                                    add(now,num(i,j,l),1,0);
                                    add(num(i,j,l),num(i,j,(l+2<=4)?l+2:l-2),1,1);
                                }
                            }
                        }
                        break;
                    }
                    case 3:{
                        for(reg l=1;l<=4;++l){
                            if(has[l]){
                                add(now,num(i,j,l),1,0);
                            }else{
                                add(num(i,j,(l+1)<=4?l+1:l-3),num(i,j,l),1,1);
                                add(num(i,j,(l+3)<=4?l+3:l-1),num(i,j,l),1,1);
                                add(num(i,j,(l+2)<=4?l+2:l-2),num(i,j,l),1,2);
                            }
                        }
                        break;
                    }
                    case 4:{
                        for(reg l=1;l<=4;++l){
                            add(now,num(i,j,l),1,0);
                        }
                        break;
                    }
                }
            }else{
                switch(tot){
                    case 0:{
                        break;
                    }
                    case 1:{
                        int pos=0;
                        for(reg l=1;l<=4;++l) if(has[l]){
                             pos=l;
                        }
                        add(num(i,j,pos),now,1,0);
                        add(num(i,j,pos%4+1),now,1,1);
                        add(num(i,j,pos==1?4:pos-1),now,1,1);
                        add(num(i,j,(pos+2<=4)?pos+2:pos-2),now,1,2);
                        break;
                    }
                    case 2:{
                        if(mp[i][j]==5||mp[i][j]==10){
                            for(reg l=1;l<=4;++l){
                                if(has[l]) add(num(i,j,l),now,1,0);
                            }
                        }else{
                            for(reg l=1;l<=4;++l){
                                if(has[l]) {
                                    add(num(i,j,l),now,1,0);
                                    add(num(i,j,(l+2<=4)?l+2:l-2),num(i,j,l),1,1);
                                }
                            }
                        }
                        break;
                    }
                    case 3:{
                        for(reg l=1;l<=4;++l){
                            if(has[l]){
                                add(num(i,j,l),now,1,0);
                            }else{
                                add(num(i,j,l),num(i,j,(l+1)<=4?l+1:l-3),1,1);
                                add(num(i,j,l),num(i,j,(l+3)<=4?l+3:l-1),1,1);
                                add(num(i,j,l),num(i,j,(l+2)<=4?l+2:l-2),1,2);
                            }
                        }
                        break;
                    }
                    case 4:{
                        for(reg l=1;l<=4;++l){
                            add(num(i,j,l),now,1,0);
                        }
                        break;
                    }
                }
            }
            if((i+j)%2==0){
                if(i>1) add(num(i,j,1),num(i-1,j,3),1,0);
                if(i<n)    add(num(i,j,3),num(i+1,j,1),1,0);
                if(j>1) add(num(i,j,4),num(i,j-1,2),1,0);
                if(j<m) add(num(i,j,2),num(i,j+1,4),1,0);
            } 
        }
    }
    while(spfa()) upda();
    //cout<<" maxflow "<<maxflow<<endl;
    if(maxflow!=le){
        puts("-1");return 0;
    }
    printf("%d",ans);
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2018/12/14 21:08:15
*/
无限之环1

暴力版(352行):

// luogu-judger-enable-o2
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define il inline
#define reg register int
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=20000+2;
const int inf=0x3f3f3f3f;
int n,m,s,t;
struct node{
    int nxt,to;
    int w,v;
}e[(5*N+4*N+N*6)*2];
int hd[5*N],cnt=1;
void add(int x,int y,int w,int v){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    e[cnt].w=w;
    e[cnt].v=v;
    hd[x]=cnt;
    
    e[++cnt].nxt=hd[y];
    e[cnt].to=x;
    e[cnt].w=0;
    e[cnt].v=-v;
    hd[y]=cnt;
}
int incf[5*N],dis[5*N];
int pre[5*N];
bool vis[5*N];
queue<int>q;
bool spfa(){
    while(!q.empty()) q.pop();
    memset(vis,0,sizeof vis);
    memset(dis,inf,sizeof dis);
    dis[s]=0;
    incf[s]=inf;
    pre[s]=0;
    q.push(s);
    while(!q.empty()){
        int x=q.front();q.pop();
        vis[x]=0;
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(e[i].w&&dis[y]>dis[x]+e[i].v){
                dis[y]=dis[x]+e[i].v;
                pre[y]=i;
                incf[y]=min(e[i].w,incf[x]);
                if(!vis[y]){
                    vis[y]=1;
                    q.push(y);
                }
            }    
        }
    }
    if(dis[t]==inf) return false;
    return true;
}
int ans,maxflow;
void upda(){
    int x=t;
    while(pre[x]){
        e[pre[x]].w-=incf[t];
        e[pre[x]^1].w+=incf[t];
        x=e[pre[x]^1].to;
    }
    ans+=incf[t]*dis[t];
    maxflow+=incf[t];
    //cout<<" ans "<<ans<<" "<<maxflow<<endl;
}
int has[10],tot;
int mp[2005][2005];
int sz[N];
int num(int x,int y,int k){//5 is itself
    return ((x-1)*m+y-1)*5+k;
}
int main(){
    rd(n);rd(m);
    s=0,t=n*m*5+1;
    for(reg i=1;i<=16;++i){
        sz[i]=sz[i>>1]+(i&1);
    }
    int le=0,ri=0;
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=m;++j){
            rd(mp[i][j]);
            if((i+j)%2==0) add(s,num(i,j,5),sz[mp[i][j]],0),le+=sz[mp[i][j]];
            else add(num(i,j,5),t,sz[mp[i][j]],0),ri+=sz[mp[i][j]];
        }
    }
    if(le!=ri){
        printf("-1");return 0;
    }
    for(reg i=1;i<=n;++i){
        for(reg j=1;j<=m;++j){
            int tmp=mp[i][j];
            tot=0;
            while(tmp){
                has[++tot]=tmp%2;tmp/=2;
            }
            tot=sz[mp[i][j]];
            int now=num(i,j,5);
            
            if((i+j)%2==0){
                switch(tot){
                    case 0:{
                        break;
                    }
                    case 1:{
                        if(mp[i][j]==1){
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,2),1,1);
                            add(now,num(i,j,3),1,2);
                            add(now,num(i,j,4),1,1);
                        }else if(mp[i][j]==2){
                            add(now,num(i,j,2),1,0);
                            add(now,num(i,j,3),1,1);
                            add(now,num(i,j,4),1,2);
                            add(now,num(i,j,1),1,1);
                        }else if(mp[i][j]==4){
                            add(now,num(i,j,3),1,0);
                            add(now,num(i,j,2),1,1);
                            add(now,num(i,j,1),1,2);
                            add(now,num(i,j,4),1,1);
                        }else if(mp[i][j]==8){
                            add(now,num(i,j,4),1,0);
                            add(now,num(i,j,3),1,1);
                            add(now,num(i,j,2),1,2);
                            add(now,num(i,j,1),1,1);
                        }
                        break;
                    }
                    case 2:{
                        if(mp[i][j]==5||mp[i][j]==10){
//    cout<<" dkfjdf "<<endl;
//                            for(reg l=1;l<=4;++l){
//                                if(has[l]) add(now,num(i,j,l),1,0);
//                            }
                            if(mp[i][j]==5){
                                add(now,num(i,j,1),1,0);
                                add(now,num(i,j,3),1,0);
                            }else{
                                add(now,num(i,j,2),1,0);
                                add(now,num(i,j,4),1,0);
                            }
                            break;
                        }
                        if(mp[i][j]==3){
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,2),1,0);
                            add(num(i,j,1),num(i,j,3),1,1);
                            add(num(i,j,2),num(i,j,4),1,1);
                        }
                        else if(mp[i][j]==6){
                            add(now,num(i,j,2),1,0);
                            add(now,num(i,j,3),1,0);
                            add(num(i,j,2),num(i,j,4),1,1);
                            add(num(i,j,3),num(i,j,1),1,1);
                        }else if(mp[i][j]==12){
                            add(now,num(i,j,3),1,0);
                            add(now,num(i,j,4),1,0);
                            add(num(i,j,3),num(i,j,1),1,1);
                            add(num(i,j,4),num(i,j,2),1,1);
                        }else{
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,4),1,0);
                            add(num(i,j,1),num(i,j,3),1,1);
                            add(num(i,j,4),num(i,j,2),1,1);
                        }
                        break;
                    }
                    case 3:{
                        if(mp[i][j]==7){
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,2),1,0);
                            add(now,num(i,j,3),1,0);
                            add(num(i,j,1),num(i,j,4),1,1);
                            add(num(i,j,2),num(i,j,4),1,2);
                            add(num(i,j,3),num(i,j,4),1,1);
                        }else if(mp[i][j]==14){
                            add(now,num(i,j,4),1,0);
                            add(now,num(i,j,2),1,0);
                            add(now,num(i,j,3),1,0);
                            add(num(i,j,4),num(i,j,1),1,1);
                            add(num(i,j,2),num(i,j,1),1,1);
                            add(num(i,j,3),num(i,j,1),1,2);
                        }else if(mp[i][j]==13){
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,4),1,0);
                            add(now,num(i,j,3),1,0);
                            add(num(i,j,1),num(i,j,2),1,1);
                            add(num(i,j,4),num(i,j,2),1,2);
                            add(num(i,j,3),num(i,j,2),1,1);
                        }else if(mp[i][j]==11){
                            add(now,num(i,j,1),1,0);
                            add(now,num(i,j,2),1,0);
                            add(now,num(i,j,4),1,0);
                            add(num(i,j,1),num(i,j,3),1,2);
                            add(num(i,j,2),num(i,j,3),1,1);
                            add(num(i,j,4),num(i,j,3),1,1);
                        }
                        break;
                    }
                    case 4:{
                        for(reg l=1;l<=4;++l){
                            add(now,num(i,j,l),1,0);
                        }
                        break;
                    }
                }
            }else{
                switch(tot){
                    case 0:{
                        break;
                    }
                    case 1:{
                        if(mp[i][j]==1){
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,2),now,1,1);
                            add(num(i,j,3),now,1,2);
                            add(num(i,j,4),now,1,1);
                        }else if(mp[i][j]==2){
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,3),now,1,1);
                            add(num(i,j,4),now,1,2);
                            add(num(i,j,1),now,1,1);
                        }else if(mp[i][j]==4){
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,2),now,1,1);
                            add(num(i,j,1),now,1,2);
                            add(num(i,j,4),now,1,1);
                        }else if(mp[i][j]==8){
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,3),now,1,1);
                            add(num(i,j,2),now,1,2);
                            add(num(i,j,1),now,1,1);
                        }
                        break;
                    }
                    case 2:{
                        if(mp[i][j]==5||mp[i][j]==10){
                            if(mp[i][j]==5){
                                add(num(i,j,1),now,1,0);
                                add(num(i,j,3),now,1,0);
                            }else{
                                add(num(i,j,2),now,1,0);
                                add(num(i,j,4),now,1,0);
                            }
                            break;
                        }
                        if(mp[i][j]==3){
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,3),num(i,j,1),1,1);
                            add(num(i,j,4),num(i,j,2),1,1);
                        }
                        else if(mp[i][j]==6){
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,4),num(i,j,2),1,1);
                            add(num(i,j,1),num(i,j,3),1,1);
                        }else if(mp[i][j]==12){
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,1),num(i,j,3),1,1);
                            add(num(i,j,2),num(i,j,4),1,1);
                        }else{
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,3),num(i,j,1),1,1);
                            add(num(i,j,2),num(i,j,4),1,1);
                        }
                        break;
                    }
                    case 3:{
                        if(mp[i][j]==7){
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,4),num(i,j,1),1,1);
                            add(num(i,j,4),num(i,j,2),1,2);
                            add(num(i,j,4),num(i,j,3),1,1);
                        }else if(mp[i][j]==14){
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,1),num(i,j,4),1,1);
                            add(num(i,j,1),num(i,j,2),1,1);
                            add(num(i,j,1),num(i,j,3),1,2);
                        }else if(mp[i][j]==13){
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,3),now,1,0);
                            add(num(i,j,2),num(i,j,1),1,1);
                            add(num(i,j,2),num(i,j,4),1,2);
                            add(num(i,j,2),num(i,j,3),1,1);
                        }else if(mp[i][j]==11){
                            add(num(i,j,1),now,1,0);
                            add(num(i,j,2),now,1,0);
                            add(num(i,j,4),now,1,0);
                            add(num(i,j,3),num(i,j,1),1,2);
                            add(num(i,j,3),num(i,j,2),1,1);
                            add(num(i,j,3),num(i,j,4),1,1);
                        }
                        break;
                    }
                    case 4:{
                        for(reg l=1;l<=4;++l){
                            add(num(i,j,l),now,1,0);
                        }
                        break;
                    }
                }
            }
            if((i+j)%2==0){
                if(i>1) add(num(i,j,1),num(i-1,j,3),1,0);
                if(i<n)    add(num(i,j,3),num(i+1,j,1),1,0);
                if(j>1) add(num(i,j,4),num(i,j-1,2),1,0);
                if(j<m) add(num(i,j,2),num(i,j+1,4),1,0);
            } 
        }
    }
    while(spfa()) upda();
//    cout<<" maxflow "<<maxflow<<endl;
    if(maxflow!=le){
        puts("-1");return 0;
    }
    printf("%d",ans);
    return 0;
}

}
signed main(){
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2018/12/14 21:08:15
*/
无限之环2

 

 

BZOJ3779: 重组病毒(4h跨夜)

终于体会到数据结构的恶心之处了。。。。

调到神经错乱,内分泌失调,,,,,

开始以为LCT写挂,

和树点涂色对比发现没错!?

于是搞标程。。。

然后发现线段树输出的值不一样?!

线段树写挂了?

遂用“线段树1模板”对照,,,并没有错!?

然后考下来多个标程(TMD都什么鬼畜码风??!)

甚至一个标程先把所有dep-1,最后再+1,,,然后让我白白多调了1h的。。

然后终于找到小范围hack数据!

跟踪发现,多query几次就对了,不query就错了!?!?

线段树pushdown挂了?!!

仔细看看并没有!

难道数组RE?

仔细看看也没有!

跟踪线段树情况!

tr[3].sum:10->12偷偷变成了12?!!?

怀疑人生.gif

然后输出tr[3].sum跟踪。。

rotate+splay之后变成12?LCT和线段树有什么关系?!

发现rotate和splay之后有一个pushup!?!?!????!?!?!?!?!

我哩个去?!?!

pushup是线段树的同名操作,,,,,这题LCT不用,,,,习惯性地写了,,,,,

pushup几次应该不会出锅啊???

因为这个题,,一边access一边线段树区间加,一边pushup的话,可能一个打标记没有下放的区间,莫名被儿子pushup一下,sum值就变回原来的了!!!!!!!

哦!!

那,就这样吧。。。。

生无可恋.jpg

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define ls (x<<1)
#define rs (x<<1|1)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=100000+5;
int n,m;
struct bian{
    int nxt,to;
}e[2*N];
int hd[N],cnt;
void add(int x,int y){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    hd[x]=cnt;
}
int dfn[N],dfn2[N],dep[N];
int f[N][20];
int rt,df,fdfn[N];
void dfs(int x,int fa,int d){
    //cout<<" dfs "<<x<<" "<<fa<<" "<<d<<" "<<df<<endl;
    dep[x]=d;
    dfn[x]=++df;
    fdfn[df]=x;
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        //cout<<" yy "<<y<<endl;
        if(y==fa) continue;
        f[y][0]=x;
        dfs(y,x,d+1);
    }
    dfn2[x]=df;
}
struct tree{
    ll sum;
    ll add;
}tr[4*N];
void pushup(int x){
    tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;
}
void build(int x,int l,int r){
    if(l==r){
        tr[x].sum=dep[fdfn[l]];
        tr[x].add=0;
        return;
    }
    int mid=(l+r)/2;
    build(x<<1,l,mid);
    build(x<<1|1,mid+1,r);
    pushup(x);
    //cout<<" sum "<<l<<" "<<r<<" : "<<tr[x].sum<<endl;
}
void pushdown(int x,int l,int r){
    if(!tr[x].add) return;
    int mid=(l+r)/2;
    //cout<<" pdpdpdpd "<<x<<endl;
    tr[x<<1].add+=tr[x].add;
    tr[x<<1].sum+=(ll)(mid-l+1)*tr[x].add;
    tr[x<<1|1].add+=tr[x].add;
    tr[x<<1|1].sum+=(ll)(r-mid)*tr[x].add;
    tr[x].add=0;
}
void upda(int x,int l,int r,int L,int R,ll c){
    //cout<<" upda "<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<c<<" "<<tr[x].sum<<" "<<tr[x].add<<" ???? "<<tr[3].sum<<endl;
    if(L<=l&&r<=R){
        tr[x].add+=c;
        tr[x].sum+=(ll)(r-l+1)*c;
        return;
    }
    pushdown(x,l,r);
    int mid=(l+r)/2;
    if(L<=mid) upda(ls,l,mid,L,R,c);
    if(mid<R) upda(rs,mid+1,r,L,R,c);
    pushup(x);
   // cout<<" back "<<l<<" "<<r<<" : "<<tr[x].sum<<" "<<tr[x<<1|1].sum<<" "<<tr[x<<1|1].sum+tr[x<<1].sum<<endl;
}
ll query(int x,int l,int r,int L,int R){
    //cout<<x<<" "<<l<<" "<<r<<" "<<L<<" "<<R<<" "<<tr[x].sum<<" "<<tr[x].add<<endl;
    if(L<=l&&r<=R){
        return tr[x].sum;
    }
    pushdown(x,l,r);ll ret=0;
    int mid=(l+r)/2;
    if(L<=mid) ret+=query(x<<1,l,mid,L,R);
    if(mid<R) ret+=query(x<<1|1,mid+1,r,L,R);
    return ret;
}
int jump(int x){
    int ret=rt;
    for(reg j=19;j>=0;--j) if(dep[f[ret][j]]>dep[x]) ret=f[ret][j];
    return ret;
}
void wrk1(int x,ll c){//upda zishu
    
    if(!x) return;
    //cout<<" wrk "<<x<<" "<<c<<" nowrt "<<rt<<endl;
    if(x==rt){
       // cout<<" rtrtrt "<<endl;
        upda(1,1,n,1,n,c);
    }
//    else if(dfn[rt]<=dfn[x]&&dfn[x]<=dfn2[rt]){
//        upda(1,1,n,dfn[x],dfn2[x],c);
//    }
    else if(dfn[x]<=dfn[rt]&&dfn[rt]<=dfn2[x]){
       // cout<<" suiergrgurhgurgh "<<endl;
        int son=jump(x);
        if(dfn[son]!=1)upda(1,1,n,1,dfn[son]-1,c);
        if(dfn2[son]!=n)upda(1,1,n,dfn2[son]+1,n,c);
    }else{
        //cout<<" son "<<x<<" "<<dfn[x]<<" "<<dfn2[x]<<" "<<c<<endl;
        upda(1,1,n,dfn[x],dfn2[x],c);
    }
}
double wrk2(int x){//query zishu
    double ret=0;
    int sz=0;
    if(x==rt){
       // cout<<" rtrtr "<<endl;
        return (double)query(1,1,n,1,n)/(double)n;
    }else if(dfn[x]<=dfn[rt]&&dfn[rt]<=dfn2[x]){
       // cout<<" uifshgugh "<<endl;
        int son=jump(x);
        sz=dfn[son]-1+n-dfn2[son];
        ret=(double)query(1,1,n,1,dfn[son]-1)+(double)query(1,1,n,dfn2[son]+1,n);
        return (double)ret/(double)sz;
    }else{
       // cout<<" sqeure "<<" "<<query(1,1,n,dfn[x],dfn2[x])<<" "<<dfn2[x]-dfn[x]+1<<endl;
        return (double)query(1,1,n,dfn[x],dfn2[x])/((double)dfn2[x]-dfn[x]+1);    
    }
}
struct node{
    int fa,ch[2];
    int r;
}t[N];
bool nrt(int x){
    return (t[t[x].fa].ch[0]==x)||(t[t[x].fa].ch[1]==x);
}
void rev(int x){
    swap(t[x].ch[0],t[x].ch[1]);
    t[x].r^=1;
}
void pd(int x){
    if(t[x].r){
        rev(t[x].ch[0]);rev(t[x].ch[1]);
        t[x].r=0;
    }
}
void rotate(int x){
    //cout<<" ro ??? "<<x<<" "<<tr[3].sum<<endl;
    int y=t[x].fa,d=t[y].ch[1]==x;
    t[t[y].ch[d]=t[x].ch[!d]].fa=y;
    if(nrt(y)) t[t[x].fa=t[y].fa].ch[t[t[y].fa].ch[1]==y]=x;
    else t[x].fa=t[y].fa;
    t[t[x].ch[!d]=y].fa=x;
    //pushup(y);
}
int sta[N];
void splay(int x){
    int y=x,z=0;
    sta[++z]=y;
    while(nrt(y)) y=t[y].fa,sta[++z]=y;
    while(z) pd(sta[z--]);
    //cout<<" splll ??? "<<tr[3].sum<<endl;
    while(nrt(x)){
        y=t[x].fa,z=t[y].fa;
        if(nrt(y)){
            rotate(((t[y].ch[0]==x)==(t[z].ch[0]==y)?y:x));
        }
        rotate(x);
    }
    //pushup(x);
}
int pre(int x){
    if(!x) return 0;
    pd(x);
    while(t[x].ch[0]) {
        pd(x);
        x=t[x].ch[0];
    }
    return x;
}
void access(int x){
    for(reg y=0;x;y=x,x=t[x].fa){
        //cout<<" ssst ??? "<<tr[3].sum<<endl;
        splay(x);
        //cout<<" st ??? "<<tr[3].sum<<endl;
        int bc=pre(t[x].ch[1]);
        int pr=pre(y);
       // cout<<" access "<<x<<" "<<y<<" pre "<<pr<<" "<<bc<<endl;
       // cout<<" be ??? "<<tr[3].sum<<endl;
        wrk1(pr,-1);
       // cout<<" pr ??? "<<tr[3].sum<<endl;
        wrk1(bc,1);
        //cout<<" bc ??? "<<tr[3].sum<<endl;
        t[x].ch[1]=y;
    }
}
void makert(int x){
    access(x);splay(x);rev(x);
}
int main(){
    
    rd(n);rd(m);
    int x,y;
    for(reg i=1;i<n;++i){
        rd(x);rd(y);
        add(x,y);add(y,x);
    }//cout<<" ahah "<<endl;
    dfs(1,0,1);
    dep[0]=-1;
    for(reg i=1;i<=n;++i){
        t[i].fa=f[i][0];
    }
    for(reg j=1;j<=19;++j){
        for(reg i=1;i<=n;++i){
            f[i][j]=f[f[i][j-1]][j-1];
        }
    }
    
    build(1,1,n);
    //cout<<"---------------------------"<<dep[15]<<" : "<<dfn[15]<<" "<<dfn2[15]<<" "<<query(1,1,n,dfn[15],dfn2[15])<<endl;
    rt=1;
    char s[233];
    
    while(m--){
        scanf("%s",s+1);
        rd(x);
        //cout<<" -----------------------rtsum "<<tr[1].sum<<" "<<endl;
        if(s[3]=='Q'){//cout<<" t3 "<<query(1,1,n,dfn[3],dfn[3])<<" t4 "<<query(1,1,n,dfn[4],dfn[4])<<" t5 "<<query(1,1,n,dfn[5],dfn[5])<<" t6 "<<query(1,1,n,dfn[6],dfn[6])<<" t7 "<<query(1,1,n,dfn[7],dfn[7])<<endl;
            printf("%.10lf\n",wrk2(x));
        }else if(s[3]=='L'){
            //cout<<"??? "<<tr[3].sum<<endl;
            access(x);
        }else if(s[3]=='C'){
            
            makert(x);
            rt=x;
        }
       
    }
    return 0;
}

}
signed main(){
//    freopen("4.in","r",stdin);
//    freopen("my.out","w",stdout);
    Miracle::main();
    return 0;
}
重组病毒

 

[九省联考2018]秘密袭击coat(研究4h题解)

官方题解思路挺新奇的。

[九省联考2018]秘密袭击coat

Chef and Sad Pairs(3h)

圆方树+虚树+树上差分的总和题目

注意错误点

[九省联考2018]秘密袭击coat

 

「LibreOJ NOI Round #1」验题(目前最长代码(+注释)400行)

动态DP好久以来第一次写,还是线段树维护轻儿子那种。

「LibreOJ NOI Round #1」验题

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define mid ((l+r)>>1)
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
    char ch;x=0;bool fl=false;
    while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);
    (fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1e6+6;
const int M=4e6+5;
int n;
int b[N][2];
int a[N],I;
int ori[N];
ll k;
int hd[N],cnt;
int bian[N][2];
struct node{
    int nxt,to;
}e[2*N];
void addedge(int x,int y){
    e[++cnt].nxt=hd[x];
    e[cnt].to=y;
    hd[x]=cnt;
}
ll mul(const ll &a,const ll &b){
    if(!a||!b) return 0;
    if(a>k+1||b>k+1) return k+2;
    return __builtin_clzll(a)+__builtin_clzll(b)<66?k+2:a*b;
}
ll add(const ll &a,const ll &b){
    return a+b>k+1?k+2:a+b;
}
struct mat{
    ll a[2][2];
    void clear(){memset(a,0,sizeof a);}
    void pre(){a[0][0]=1;a[1][1]=1;a[0][1]=a[1][0]=0;}
    void init(){a[0][0]=a[1][0]=a[0][1]=1;a[1][1]=0;}
    mat operator *(const mat&b){
        mat c;
//        for(reg i=0;i<1;++i){
//            for(reg k=0;k<1;++k){
//                for(reg j=0;j<1;++j){
//                    c.a[i][j]=add(c.a[i][j],mul(a[i][k],b.a[k][j]));
//                }
//            }
//        }
        c.a[0][0]=add(mul(a[0][0],b.a[0][0]),mul(a[0][1],b.a[1][0]));
        c.a[0][1]=add(mul(a[0][0],b.a[0][1]),mul(a[0][1],b.a[1][1]));
        c.a[1][0]=add(mul(a[1][0],b.a[0][0]),mul(a[1][1],b.a[1][0]));
        c.a[1][1]=add(mul(a[1][0],b.a[0][1]),mul(a[1][1],b.a[1][1]));
        return c;
    }
    void op(){
        cout<<a[0][0]<<" "<<a[0][1]<<endl;
        cout<<a[1][0]<<" "<<a[1][1]<<endl;
    }
}st[N],base,nowdp;

int dfn[N],top[N],dep[N],son[N],sz[N],fa[N];
int fdfn[N];
int low[N];
int df;
int totson[N];
int num[N];//i is i's fa's num[i] son
int in[N];//0 not 1 yes
ll f[N][2];

namespace seg1{//get lian
int tot;
int ls[M],rs[M];
mat data[M];
struct tr1{
    int ss,nd;
    int rt;
    void pushup(int x){
    //    cout<<"pushup "<<x<<" "<<ls[x]<<" "<<rs[x]<<endl;
    //    data[rs[x]].op();
    //    data[ls[x]].op();
        data[x]=data[rs[x]]*data[ls[x]];
    //    cout<<endl;
    //    data[x].op();
    }
    mat get(){
        return data[rt];
    }
    void build(int &x,int l,int r){
        x=++tot;
    //    cout<<" x "<<x<<" "<<l<<" "<<r<<endl;
        if(l==r){
        //    cout<<"l==r "<<fdfn[l]<<endl;
        //    st[fdfn[l]].op();
            data[x]=st[fdfn[l]];return;
        }
        build(ls[x],l,mid);build(rs[x],mid+1,r);
        pushup(x);
    //    cout<<" bac "<<x<<" "<<endl;
    //    data[x].op();
    }
    void chan(int p,ll c0,ll c1){
        upda(rt,ss,nd,p,c0,c1);
    }
    mat que(int L,int R){
        return query(rt,ss,nd,L,R);
    }
    mat query(int x,int l,int r,int L,int R){
        if(L<=l&&r<=R){
            return data[x];
        }
        mat ret;
        ret.pre();
        if(mid<R) ret=ret*query(rs[x],mid+1,r,L,R);
        if(L<=mid) ret=ret*query(ls[x],l,mid,L,R);
        return ret;
    }
    void upda(int x,int l,int r,int p,ll c0,ll c1){
        if(l==r){
            data[x].a[0][0]=c0;
            data[x].a[1][0]=c0;
            data[x].a[0][1]=c1;
            return;
        }
        if(p<=mid) upda(ls[x],l,mid,p,c0,c1);
        else upda(rs[x],mid+1,r,p,c0,c1);
        pushup(x);
    }
};

}using seg1::tr1;
tr1 t1[N];

int mem[N];
namespace seg2{//get son
int tot;
int ls[M],rs[M];
ll s0[M],s1[M];
struct tr2{
    int sz,rt;
    void pushup(int x){
        s0[x]=mul(s0[ls[x]],s0[rs[x]]);
        s1[x]=mul(s1[ls[x]],s1[rs[x]]);
    }
    void build(int &x,int l,int r){
        x=++tot;
        if(l==r){
            s0[x]=f[mem[l]][0]+f[mem[l]][1];
            s1[x]=f[mem[l]][0];
            return;
        }
        build(ls[x],l,mid);build(rs[x],mid+1,r);
        pushup(x);
    }
    void chan(int p,ll c0,ll c1){
        upda(rt,1,sz,p,c0,c1);
    }
    void upda(int x,int l,int r,int p,ll c0,ll c1){
        if(l==r){
            s0[x]=c0;
            s1[x]=c1;
            return;
        }
        if(p<=mid) upda(ls[x],l,mid,p,c0,c1);
        else upda(rs[x],mid+1,r,p,c0,c1);
        pushup(x);
    }
    void spe(int &x){
        x=++tot;
        s0[x]=1;s1[x]=1;
    }
    ll get0(){
    //    cout<<" rtrt "<<rt<<endl;
        return s0[rt];
    }
    ll get1(){
        return s1[rt];
    }
};

}using seg2::tr2;
tr2 t2[N];

int sta[N],tp;
void dfs1(int x,int d){
//    cout<<"dfs1 "<<x<<" "<<d<<endl;
    dep[x]=d;
    sz[x]=1;
    if(!in[x])f[x][0]=1;
    else f[x][1]=1;
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==fa[x]) continue;
        fa[y]=x;
        dfs1(y,x);
        sz[x]+=sz[y];
        if(sz[y]>sz[son[x]]) son[x]=y;
    }
}
void dfs2(int x){
//    cout<<" dfs2 "<<x<<" "<<son[x]<<endl;
    dfn[x]=++df;
    sta[++tp]=x;
    fdfn[df]=x;
    if(!top[x]) top[x]=x;
    if(son[x]) top[son[x]]=top[x],++totson[x],dfs2(son[x]);
    st[x].init();
    
    for(reg i=hd[x];i;i=e[i].nxt){
        int y=e[i].to;
        if(y==son[x]) continue;
        if(y==fa[x]) continue;
        num[y]=totson[x];
        ++totson[x];
        dfs2(y);
        if(in[x]){
            st[x].a[0][1]*=(f[y][0]);
        }else{
            st[x].a[0][0]*=(f[y][0]+f[y][1]);
            st[x].a[1][0]*=(f[y][0]+f[y][1]);
        }
    }
    if(in[x]) st[x].a[0][0]=st[x].a[1][0]=0;
    else st[x].a[0][1]=0;
//    cout<<" mat-------------------------------"<<x<<endl;
    //st[x].op();
    
//        t1[top[x]].ss=dfn[top[x]];
//        t1[top[x]].nd=dfn[x];
//        t1[top[x]].build(t1[top[x]].rt,t1[top[x]].ss,t1[top[x]].nd);
//        
        
    if(top[x]==x){    
    //    cout<<" zhong ss "<<x<<" nd "<<sta[tp]<<endl;
        t1[x].ss=dfn[x];
        t1[x].nd=dfn[sta[tp]];
        t1[x].build(t1[x].rt,t1[x].ss,t1[x].nd);
    //    cout<<" t1rt "<<endl;t1[x].get().op();
        int z;
        do{
            z=sta[tp];
            --tp;
        }while(z!=x);
    }
    
    if(totson[x]==0){//leaf 
    
    
        t2[x].spe(t2[x].rt);    
    //    cout<<"gen "<<t2[x].rt<<endl;
    }
    else if(totson[x]==1){
        t2[x].spe(t2[x].rt);
        
    }
    else if(totson[x]>1){
    //    cout<<" has son "<<x<<" "<<totson[x]<<endl;
        int lp=0;
        for(reg i=hd[x];i;i=e[i].nxt){
            int y=e[i].to;
            if(y==fa[x]||y==son[x]) continue;
            mem[++lp]=y;
        }
        t2[x].sz=lp;
        t2[x].build(t2[x].rt,1,lp);
    }
}
mat upda(int x){
    mat ret;
    ret.clear();
   // cout<<" upda "<<x<<" in "<<in[x]<<endl;
    while(x){
        if(in[x]==0){//must not
      //      cout<<"get0 "<<t2[x].rt<<" "<<t2[x].get0()<<endl;
            t1[top[x]].chan(dfn[x],t2[x].get0(),0);
        }else if(in[x]==1){//must yes
            t1[top[x]].chan(dfn[x],0,t2[x].get1());
        }else{//either
      //      cout<<" g0 g1 "<<t2[x].get0()<<" "<<t2[x].get1()<<endl;
            t1[top[x]].chan(dfn[x],t2[x].get0(),t2[x].get1());
        }
    //    if(x==1)t1[top[x]].que(2,3).op(),t1[top[x]].que(1,1).op();
      //  cout<<" difd "<<endl;
      //  t1[top[x]].get().op();
        ret=base*t1[top[x]].get();
        x=top[x];
        if(fa[x]){
            t2[fa[x]].chan(num[x],add(ret.a[0][0],ret.a[0][1]),ret.a[0][0]);
        }
        x=fa[x];
    }
   // cout<<"ret "<<ret.a[0][0]<<" "<<ret.a[0][1]<<endl;
    return ret;
}
int main(){
    rd(n);
    scanf("%lld",&k);
    base.a[0][0]=1;
    
    for(reg i=1;i<n;++i) rd(b[i][0]),++b[i][0];
    for(reg i=1;i<n;++i) {
        rd(b[i][1]);
        ++b[i][1];
        addedge(b[i][0],b[i][1]);
        addedge(b[i][1],b[i][0]);
    }
    rd(I);
    for(reg i=1;i<=I;++i) rd(a[i]),++a[i],in[a[i]]=1,ori[a[i]]=1;
    sort(a+1,a+I+1);
    
    if(k==0){
        for(reg i=1;i<=I;++i){
            printf("%d ",a[i]-1);
        }
        return 0;
    }
    dfs1(1,1);
  //  cout<<" after dfs1 "<<endl;
    dfs2(1);
   // cout<<" after dfs2 "<<endl;
//    cout<<nowdp.a[0][0]+nowdp.a[0][1]<<endl;
    
    int lcp=I;//warning!! num 
    ll remain=k;
    for(reg i=a[lcp]+1;i<=n;++i){
        in[i]=2;
        nowdp=upda(i);
    }
    ll tot=add(nowdp.a[0][0],nowdp.a[0][1]);
    int lp=0;
    //has=0;
   // cout<<" after last zero "<<endl;
    if(tot-1<remain){
        remain-=max(1LL*0,tot-1);
        int ptr=a[lcp]-1;
        for(;lcp;--lcp){
          //  cout<<"lcp "<<lcp<<endl;
            in[a[lcp]]=0;
            nowdp=upda(a[lcp]);
            tot=add(nowdp.a[0][0],nowdp.a[0][1]);
          //  cout<<"tot "<<tot<<endl;
            if(tot-1<remain){
                remain-=tot-1;
                in[a[lcp]]=2;
                nowdp=upda(a[lcp]);
            }else{
                break;
            }
            ptr=a[lcp]-1;
            while(ptr&&ori[ptr]!=1){
                in[ptr]=2;
                nowdp=upda(ptr);
                --ptr;
            }
        }
        if(!lcp){
            return 0;
        }
    }
  //  cout<<" after lcp "<<lcp<<endl;
//    else{
//        lp=a[lcp]+1;
//        for(reg i=lp;i<=n;++)
//    }
    lp=a[lcp]+1;
    for(reg i=lp;i<=n;++i){
     //   cout<<" ii "<<i<<" ---------------- "<<remain<<endl;
        in[i]=1;
        nowdp=upda(i);
        tot=add(nowdp.a[0][0],nowdp.a[0][1]);
       // cout<<" tot "<<tot<<endl;
        if(tot<remain){
            remain-=tot;
            in[i]=0;
            nowdp=upda(i);
        }else{
            --remain;
        }
        if(remain==0) break;
    }
    for(reg i=1;i<=n;++i){
        if(in[i]==1){
            printf("%d ",i-1);
        }
    }
    return 0;
}

}
signed main(){
//    freopen("61.in","r",stdin);
//    freopen("my.out","w",stdout);
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
   Date: 2019/2/20 11:04:52
*/


 
 
View Code

 

CF704E Iron Man

写计算几何还是真的恶心,,,

前后经历4h还是不能调过去。

orz了标程,发现,存线段还是存起点终点斜率比较好,保留k*x+b,b会损失精度。

求交的话,就当做是追及问题

 

[国家集训队]JZPSTR 

bitset处理0~9的出现情况,

插入删除查询都是移位操作。

4h写了6个k,怒拿倒数第一

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int sub(int x,int y){return ad(x,mod-y);}
il int mul(int x,int y){return (ll)x*y%mod;}
il void inc(int &x,int y){x=ad(x,y);}
il void inc2(int &x,int y){x=mul(x,y);}
il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
}
//using namespace Modulo;
#define ull unsigned long long
namespace Miracle{
const int w=64;
pii be(int x){
    if(x<0) return mk(-1,-233);
    return mk(x/w,x%w);
}
int sz(ull x){
    return __builtin_popcountll(x);
}
ull pw[w+2];
ull all[w+2];
char s[2000000+3];
struct bit{
    vector<ull>f;
    il ull &operator[](const int &x){return f[x];}
    il const ull &operator[](const int &x) const {return f[x];}
    void resize(int n){
        f.resize(n/w+1);
    }
    void set(int x){
        pii now=be(x);
        //cout<<" set "<<x<<" sz "<<f.size()<<" : "<<now.fi<<" "<<now.se<<endl;
        f[now.fi]|=pw[now.se];
    }
    void reset(int x){
        pii now=be(x);
        if((f[now.fi]>>now.se)&1) f[now.fi]-=pw[now.se];
    }
    int size() const{
        return f.size();
    }
    int count(){
        int ret=0;
        for(solid x:f){ret+=sz(x);}return ret;
    }
    ull val(int l,int r){
        //cout<<" val "<<l<<" "<<r<<endl;
        if(l>r) return 0;
        pii L=be(l),R=be(r);
        //cout<<" L "<<L.fi<<" "<<L.se<<" R "<<R.fi<<" "<<R.se<<endl;
        if(L.fi>=(int)f.size())  return 0;
        if(R.fi<0) return 0;
        
        if(R.fi>=(int)f.size()){
            R=mk(f.size()-1,w-1);
        }
        if(L.fi<0){
            L=mk(0,0);
        }
        
        
        if(L.fi==R.fi){
            ull v=f[L.fi];
            //cout<<" same "<<v<<" "<<(v&all[R.se+1])<<endl;
            return (((v&all[R.se+1])-(v&(all[L.se])))>>L.se);
        }else{
            //ull ret=((f[R.fi]&all[R.se+1])<<(w-L.se))+((f[L.fi]-(f[L.fi]&(all[L.se])))>>L.se);
            //cout<<" ret "<<ret<<endl;
            return ((f[R.fi]&all[R.se+1])<<(w-L.se))+((f[L.fi]-(f[L.fi]&(all[L.se])))>>L.se);
        }
    }
    bit friend operator <<(bit &a,int c){
        bit f;f.f.resize(a.f.size());
        for(reg i=0;i<a.size();++i){
            f[i]=a.val(i*w+c,i*w+w-1+c);
        }
        return f;
    }
    bit friend operator >>(bit &a,int c){
        bit f;f.f.resize(a.f.size());
        for(reg i=a.size()-1;i>=0;--i){
            f[i]=a.val(i*w-c,i*w+w-1-c);
        }
        return f;
    } 
    void shift(int tp,int st,int c){
        //cout<<" shift "<<st<<" "<<c<<endl;
        if(tp==0){//go left
            pii pos=be(st-c);
            
            for(reg i=pos.fi;i<(int)f.size();++i){
                int l=i*w+c,r=i*w+w-1+c;
                if(i==pos.fi){
                    f[i]=(f[i]&all[pos.se])+(val(st,r)<<pos.se);
                }
                else{
                    f[i]=val(l,r);
                }
            }
            resize(f.size()*w-c);
        }else{//go right
            pii pos=be(st);
            resize(f.size()*w+c);
            for(reg i=(int)f.size()-1;i>=0;--i){
                int l=i*w-c,r=i*w+w-1-c;
                ull tmp;
                if(r<st) tmp=0;
                else if(l<st){
                    tmp=val(st,r);
                }else{
                    tmp=val(l,r);
                }
                
                if(i==pos.fi){
                    if(!tmp) f[i]=(f[i]&all[pos.se]);
                    else f[i]=(f[i]&all[pos.se])+(tmp<<(pos.se+c));
                    break;
                }
                else{
                    if(r<st) f[i]=0;
                    else if(l<st){
                        f[i]=val(st,r)<<(st-l);
                    }else{
                        f[i]=val(l,r);
                    }
                }
            }    
        }
    }
    
    bit friend operator &(const bit &a,const bit &b){
        bit c=a;
        for(reg i=0;i<(int)c.size();++i){
            c.f[i]&=b.f[i];
        }
        return c;
    }
    void op(){
        //cout<<" op "<<f.size()<<endl;
        for(reg i=0;i<f.size();++i){
            for(reg j=0;j<w;++j){
                cout<<((f[i]>>j)&1);
            }
        }
        //cout<<endl;
    }
    bit get(int l,int r){
        //cout<<" get "<<l<<" "<<r<<endl;
        int len=r-l+1;
        bit g;g.resize(len);
        for(reg i=0;i<(int)g.size();++i){
            int nl=i*w+l,nr=i*w+w-1+l;
            //cout<<" gegeeg  "<<i<<endl;
            g[i]=val(nl,min(nr,r));
        }
        return g;
    }
}f[10],h[10],as;
int vis[10];
int main(){
    pw[0]=1;
    for(reg i=1;i<=w;++i){
        pw[i]=pw[i-1]*2;
        all[i]=pw[i]-1;
    }
    int m;
    rd(m);
    int op,l,r,x;
    
    while(m--){
        rd(op);
        if(op==0){
            rd(x);scanf("%s",s+1);
            int len=strlen(s+1);
            //cout<<" len "<<len<<endl;
            for(reg i=0;i<=9;++i){
                f[i].shift(1,x,len);    
            }
            ///cout<<" after shift "<<endl;
            ///for(reg i=0;i<=9;++i){
            ///    cout<<"num i "<<i<<endl;
            ///    f[i].op();
            //}
            for(reg i=1;i<=len;++i){
                int c=s[i]-'0';
                f[c].set(x+i-1);
            }
            //cout<<" end set"<<endl;
            //for(reg i=0;i<=9;++i){
            //    cout<<"num i "<<i<<endl;
            //    f[i].op();
            //}
        }else if(op==1){
            rd(l);rd(r);
            for(reg i=0;i<=9;++i){
                f[i].shift(0,r,r-l);
            }
        }else{
            rd(l);rd(r);--r;scanf("%s",s+1);
            int len=strlen(s+1);
            memset(vis,0,sizeof vis);
            as.resize(r-l+1);
            for(reg i=0;i<as.size();++i){
                as[i]=all[w];
            }
            //cout<<" count "<<as.count()<<endl;
            //as.op();
            for(reg i=1;i<=len;++i){
                //cout<<" -------- "<<i<<endl;
                int c=s[i]-'0';
                if(!vis[c]){
                    vis[c]=1;
                    h[c]=f[c].get(l,r);
                }
                //cout<<" h[c] "<<h[c].count()<<endl;
                //h[c].op();
                bit lp=h[c];
                lp=lp<<(i-1);
                //cout<<" lp "<<lp.count()<<endl;
                //lp.op();
                as=as&(lp);
                //cout<<" count "<<as.count()<<endl;
                //as.op();
            }
            printf("%d\n",as.count());
        }
    }
    return 0;
}

}
signed main(){
    // freopen("my.out","w",stdout);
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
*/
View Code

注意(1<<x)1是int,还是预处理pw[i]=2^i比较稳妥。 

posted @ 2018-06-02 08:34  *Miracle*  阅读(5743)  评论(6编辑  收藏  举报