模拟赛

以后不给题解的模拟赛,死也不做,
我这么菜,你还不给我题解

T1不会
没题解,std不懂
trick还是太菜,唉
自己想的大概是
枚举每个点处理包含的矩阵,展开平方,对于拆除改点的部分维护前缀和,这个前缀和类似与带一个二项式荣斥的求和式
然后对于另一部分可以把矩阵分治
在合并的时候维护一下矩形的匹配轮廓
WA,可能那个地方没处理或没考虑到吧....

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define putk() putchar(' ')
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
ll read(){
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
void put(ll a){
    if(a<0)putchar('-'),a=-a;
    int top=0,q[20];
    while(a)q[++top]=a%10,a/=10;
    top=max(top,1);
    while(top--)putchar('0'+q[top+1]);
}
//head
#define N 3100 
#define int long long 
ll a[N][N];
bool p[N][N];
int b[N][N];
int n;
const int xt[]={0,1,0,-1};
const int yt[]={1,0,-1,0};
main(){ 
    freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); 
    n=read();
    int x=1,y=1,k=0;
    int tot=1;
    rep(i,1,n)
        rep(j,1,n)p[i][j]=1;
    rep(i,1,n*n){
        b[x][y]=tot;
        p[x][y]=0;
        if(i==n*n)break;
        ++tot;

        while(!p[x+xt[k]][y+yt[k]])k=(k+1)%4;
        x+=xt[k];
        y+=yt[k];
    }
    ll ans=0;
    rep(i,1,n)
        rep(j,1,n){
            ll t=b[i][j];
            ans=mo(ans-t*i*j%pp*t%pp*(n-i+1)%pp*(n-j+1),pp);
            a[i][j]=mo(b[i][j]*i%pp*j%pp+a[i-1][j]+a[i][j-1]-a[i-1][j-1],pp);
            ans=(ans+2*a[i][j]*t%pp*(n-i+1)%pp*(n-j+1)%pp)%pp;
        }
    rep(i,1,n)
        per(j,n,1){
            ll t=b[i][j];
            a[i][j]=mo(b[i][j]*i%pp*(n-j+1)+a[i-1][j]+a[i][j+1]-a[i-1][j+1],pp);
            ans=(ans+2*a[i-1][j+1]*t%pp*(n-i+1)%pp*j)%pp;
        }   
    cout<<ans;
    return 0;
}

T2
二分,单调队列维护最大最下,盼区间个数瞎写

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define putk() putchar(' ')
ld eps=1e-9;
ll pp=1000000007;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
ll read(){
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
void put(ll a){
    if(a<0)putchar('-'),a=-a;
    int top=0,q[20];
    while(a)q[++top]=a%10,a/=10;
    top=max(top,1);
    while(top--)putchar('0'+q[top+1]);
}
//head
#define N 410000
int a[N],q1[N],q2[N];
ll k;
int n;
bool check(int kk){
    int l1=1,r1=1,l2=1,r2=1;
    q1[1]=1;q2[1]=1;
    int z=1;
    ll ans=0;
    if(kk==1)ans=1;
    else ans=0;
    rep(i,2,n){
        while(l1<=r1 && a[q1[r1]]>=a[i])--r1;
        q1[++r1]=i;
        while(l2<=r2 && a[q2[r2]]<=a[i])--r2;
        q2[++r2]=i;
        while(z<i){
                int t1=l1,t2=l2;
                ++z;
                while(q1[t1]<z)++t1;
                while(q2[t2]<z)++t2;
                if(a[q2[t2]]-a[q1[t1]]>=kk){
                    l1=t1;
                    l2=t2;
                }
                else{
                    --z;
                    break;
                }
        }
        if(a[q2[l2]]-a[q1[l1]]>=kk)ans+=z;
    }
    return ans>=k;
}
int main(){
    freopen("kth.in","r",stdin);
    freopen("kth.out","w",stdout);
    n=read();k=read();
    rep(i,1,n)a[i]=read();
    int l=0,r=1000000000;
    while(l<r){
        int mid=(l+r+1)/2;
        if(check(mid))l=mid;
        else r=mid-1;
    }
    cout<<l<<endl;
    return 0;
    return 0;
}

T3
树上哈希判断同构

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<map>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
const double pi=acos(-1);
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
#define clr(a) memset(a,0,sizeof a)
#define pb push_back
#define mp make_pair
#define putk() putchar(' ')
ld eps=1e-9;
ll p1=1000000007;
ll p2=1000000009;
ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
ll read(){
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
void put(ll a){
    if(a<0)putchar('-'),a=-a;
    int top=0,q[20];
    while(a)q[++top]=a%10,a/=10;
    top=max(top,1);
    while(top--)putchar('0'+q[top+1]);
}
//head
#define N 210000
map<ll,bool>G1,G2;
int head[N],q[N],fa[N][20],v[N],num,next[N],dep[N],len1,len2,n,m;
char str[N];
ll b1[N],inv1[N],hash1_1[N][26],hash2_1[N][26],ans[2][26];
ll b2[N],inv2[N],hash1_2[N][26],hash2_2[N][26],ans2[2][26];
bool vis[N];
int f[26];
void add(int x,int y){
    v[++num]=y;next[num]=head[x];head[x]=num;
}
void bfs(){
    int t=0,w=1;
    q[1]=1;
    vis[1]=1;
    hash1_1[1][str[1]-'a']=hash2_1[1][str[1]-'a']=1;
    hash1_2[1][str[1]-'a']=hash2_2[1][str[1]-'a']=1;
    while(t<w){
        int u=q[++t];
        for(int i=1;(1<<i)<=dep[u];i++)fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u];i;i=next[i])
            if(!vis[v[i]]){
                vis[v[i]]=1;
                q[++w]=v[i];
                fa[v[i]][0]=u;
                dep[v[i]]=dep[u]+1;
                rep(j,0,25){
                hash1_1[v[i]][j]=(hash1_1[u][j]*31+((str[v[i]]-'a')==j))%p1;
                hash2_1[v[i]][j]=(hash2_1[u][j]+b1[dep[v[i]]]*((str[v[i]]-'a')==j))%p1;
                hash1_2[v[i]][j]=(hash1_2[u][j]*37+((str[v[i]]-'a')==j))%p2;
                hash2_2[v[i]][j]=(hash2_2[u][j]+b2[dep[v[i]]]*((str[v[i]]-'a')==j))%p2;
                }
            }
    }
}
int lca(int x,int y){
    if(dep[y]>dep[x])swap(x,y);
    for(int i=18;i>=0;i--)
        if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
    if(x==y)return x;
    for(int i=18;i>=0;i--)
        if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}

int find(int x){
    if(x==f[x])return x;
    return f[x]=find(f[x]);
}
ll work1_1(int x,int y,int k){
    return mo(hash1_1[y][k]-hash1_1[fa[x][0]][k]*b1[dep[y]-dep[x]+1],p1);
}
ll work2_1(int x,int y,int k){
    return mo(hash2_1[x][k]-hash2_1[fa[y][0]][k],p1)*inv1[dep[y]]%p1;
}
ll work1_2(int x,int y,int k){
    return mo(hash1_2[y][k]-hash1_2[fa[x][0]][k]*b2[dep[y]-dep[x]+1],p2);
}
ll work2_2(int x,int y,int k){
    return mo(hash2_2[x][k]-hash2_2[fa[y][0]][k],p2)*inv2[dep[y]]%p2;
}
void work(int x,int y,int len,ll *ans1,ll *ans2){
    int z=lca(x,y);
    len=dep[x]-dep[z]+dep[y]-dep[z]+1;
    rep(i,0,25){
        ans1[i]=mo(work1_1(z,y,i)+work2_1(x,z,i)*b1[dep[y]-dep[z]]-((str[z]-'a')==i)*b1[dep[y]-dep[z]],p1);
        ans2[i]=mo(work1_2(z,y,i)+work2_2(x,z,i)*b2[dep[y]-dep[z]]-((str[z]-'a')==i)*b2[dep[y]-dep[z]],p2);
    }
    rep(i,0,25)
        if(find(i)!=i){
            ans1[find(i)]=(ans1[find(i)]+ans1[i])%p1,ans1[i]=0;
            ans2[find(i)]=(ans2[find(i)]+ans2[i])%p2,ans2[i]=0;
        }
}
bool check(){
    if(len1!=len2)return 0;
    ll tot1=0,tot2=0,s1=0,s2=0,rec1=0,rec2=0;
    rep(i,0,25){
    //  printf("%I64d %I64d %I64d %I64d\n",ans[0][i],ans[1][i],ans2[0][i],ans2[1][i]);
        if(ans[0][i]!=ans[1][i])++tot1,rec1=mo(ans[0][i]-ans[1][i],p1);
        if(ans2[0][i]!=ans2[1][i])++tot2,rec2=mo(ans2[0][i]-ans2[1][i],p2);
    }
    if(tot1!=0 && tot1!=2)return 0;
    if(tot2!=0 && tot2!=2)return 0;
    if(tot1==0 && tot2==0)return 1;
    return G1[rec1] && G2[rec2];
}
char ss[100];
int main(){
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    n=read();m=read();
    scanf("%s",str+1);
    rep(i,2,n){
        int x=read(),y=read();
        add(x,y);
        add(y,x);
    }
    b1[0]=1;
    rep(i,1,n)b1[i]=b1[i-1]*31%p1;
    inv1[0]=1;
    inv1[1]=powmod(31,p1-2,p1);
    rep(i,2,n)inv1[i]=inv1[i-1]*inv1[1]%p1;
    rep(i,0,n)G1[b1[i]]=1,G1[mo(-b1[i],p1)]=1;
    
    b2[0]=1;
    rep(i,1,n)b2[i]=b2[i-1]*37%p2;
    inv2[0]=1;
    inv2[1]=powmod(37,p2-2,p2);
    rep(i,2,n)inv2[i]=inv2[i-1]*inv2[1]%p2;
    G1[0]=1;G2[0]=1;
    rep(i,0,n)G2[b2[i]]=1,G2[mo(-b2[i],p2)]=1;
    bfs();
/*  cout<<dep[6]<<endl;
    cout<<hash1[1][0]<<endl;
    cout<<hash1[8][0]<<endl;
    cout<<hash1[6][0]<<endl;
    cout<<work1(1,6,0)<<endl;*/
    while(m--){
        int kk=read(),l1=read(),r1=read(),l2=read(),r2=read();
        rep(i,0,25)ans[0][i]=ans[1][i]=0;
        rep(i,0,25)ans2[0][i]=ans2[1][i]=0;
        rep(i,0,25)f[i]=i;
        while(kk--){
            scanf("%s",ss);
            f[find(ss[0]-'a')]=find(ss[1]-'a');
        }
        work(l1,r1,len1,ans[0],ans2[0]);
        work(l2,r2,len2,ans[1],ans2[1]);
        if(check())puts("YES");
        else puts("NO");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sssy/p/9439380.html