zoukankan      html  css  js  c++  java
  • 【集训队互测2016】消失的源代码

    SOL:

       毒瘤题。做一个两个点还觉得这道题很有意思,但10个点写下来就是心累了。

      point 1:

         对小数据观察发现每个字母唯一确定另一个字母。把26个字母之间的映射关系打表就好了。

    #include<bits/stdc++.h>
    using namespace std;
    char ch[107]="yfrbkgimujvphatdsnelozcxwq";
    int T;
    char p[1000007];
    signed main() {
        freopen("input1.txt","r",stdin);
        freopen("output1.txt","w",stdout);
        scanf("%d",&T);
        scanf("%d",&T);
        while (T--) {
            scanf("%s",p+1); int len=strlen(p+1);
            for (int i=1;i<=len;i++) putchar(ch[p[i]-'a']);
            putchar(10);
        }
    }

    point 2:

    一拿到手,就发现这个函数的增长是O(N^2)的。写了个高消发现系数是2016 4 10 ,但是跑不过样例,所以把1到20全部打出来看了一遍,发现应该是膜了一个数。

    #include<bits/stdc++.h>
    #define N 205
    using namespace std;
    const double eps=1e-8;
    int n;
    double a[N][N],del;
    bool gauss(){
        for(int i=1;i<=n;i++){
            int k=i;
            for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>fabs(a[k][i]))k=j;
            if(fabs(del=a[k][i])<eps)return 0;
            for(int j=i;j<=n+1;j++)swap(a[i][j],a[k][j]);
            for(int j=i;j<=n+1;j++)a[i][j]/=del;
            for(k=1;k<=n;k++)if(k!=i){
                del=a[k][i];
                for(int j=i;j<=n+1;j++)a[k][j]-=a[i][j]*del;
            }
        }
        return 1;
    }
    int T;
    long long p;
    __int128 x;
    #define mo (243990-10657)
    void write(__int128 x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(__int128 x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(__int128 x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    
    int main(){
        freopen("input2.txt","r",stdin);
        freopen("output2.txt","w",stdout);
        scanf("%d",&T); scanf("%d",&T);
        while (T--) {
            scanf("%lld",&p);
            x=p;
    //        printf("%lld
    ",);
            writeln((x*x*2016+4*x+10)%mo);
        }
    //    cerr<<sqrt(100/pi);
    }

    point 3:

    方法同point 2吧,应该看到出应该是O(N^0.5)这个级别的。算了下系数,发现是根号 π。

    #include<bits/stdc++.h>
    #define N 205
    using namespace std;
    const double eps=1e-8;
    int n;
    double a[N][N],del;
    bool gauss(){
        for(int i=1;i<=n;i++){
            int k=i;
            for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>fabs(a[k][i]))k=j;
            if(fabs(del=a[k][i])<eps)return 0;
            for(int j=i;j<=n+1;j++)swap(a[i][j],a[k][j]);
            for(int j=i;j<=n+1;j++)a[i][j]/=del;
            for(k=1;k<=n;k++)if(k!=i){
                del=a[k][i];
                for(int j=i;j<=n+1;j++)a[k][j]-=a[i][j]*del;
            }
        }
        return 1;
    }
    int T;
    long long p;
    __int128 x;
    #define mo (243990-10657)
    void write(__int128 x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
    inline void writeln(__int128 x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('
    '); }
    inline void writel(__int128 x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
    #define pi acos(-1)
    int main(){
        freopen("input3.txt","r",stdin);
        freopen("output3.txt","w",stdout);
        scanf("%d",&T); scanf("%d",&T);
        while (T--) {
            scanf("%lld",&p);
            printf("%lld
    ",(int)sqrt(p/pi));
    //        writeln((x*x*2016+4*x+10)%mo);
        }
    //    cerr<<sqrt(100/pi);
    }

    point 4:

    怎么说呢,长得像一张图,然后发现完全图的时候  answer=n*n,链的时候也是这样的,但边集为空的时候为n,所以应该能猜出来是sigma 联通图大小的平方。

    #include<bits/stdc++.h>
    #define N 200007
    using namespace std;
    long long ans,f[N],siz[N];
    int T,n,m,x,y,a,b;
    int gf(int x){
        return x==f[x]?x:f[x]=gf(f[x]);
    }
    signed main () {
    //    T=1;
        freopen("input4.txt","r",stdin);
        freopen("output4.txt","w",stdout);
    #include<bits/stdc++.h>
    #define N 200007
    #define SIZ 24
    #define eho(x) for(int i=head[x];i;i=net[i])
    #define v fall[i]
    using namespace std;
    long long ans,dep[N],anw;
    int T,n,m,x,y,z,f[N][SIZ],a,b,dd[N],fall[N<<1],net[N<<1],tot,head[N],cost[N];
    inline void add(int x,int y,int co) {
        fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=co;
    }
    void dfs(int x,int fa) {
    //    cerr<<x<<endl;
        dd[x]=dd[fa]+1;
        f[x][0]=fa; 
        for (int i=1;i<SIZ;i++) 
         f[x][i]=f[f[x][i-1]][i-1];
        eho(x) if (v!=fa) dep[v]=dep[x]+cost[i],dfs(v,x);
    }
    int pku(int x,int y){
        if (dd[x]<dd[y]) swap(x,y);
        for (int i=SIZ-1;~i;i--) if (dd[f[x][i]]>=dd[y]) x=f[x][i];
        if (x==y) return x;
        for (int i=SIZ-1;~i;i--) 
         if (f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    signed main () {
    //    T=1;
    //    freopen("test.txt","r",stdin);
        freopen("input5.txt","r",stdin);
        freopen("output5.txt","w",stdout);
        scanf("%d",&T); scanf("%d",&T);
        while (T--) {
    //        memset(f,0,sizeof f);
            memset(head,0,sizeof head); tot=0;
            scanf("%d%d",&n,&m);anw=0;
            for (int i=1;i<n;i++)  {
                scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z);
            }
            dfs(1,0);
            while (m--) {
                scanf("%d%d",&x,&y);
                ans=dep[x]+dep[y]-2*dep[pku(x,y)];
                anw^=ans;
            }
            printf("%lld
    ",anw);
        } return 0;
    }
    
    
    
    
        scanf("%d",&T); scanf("%d",&T);
        while (T--) {
            scanf("%d%d",&n,&m);ans=0;
            for (int i=1;i<=n;i++) f[i]=i,siz[i]=0;
            while (m--) {
                scanf("%d%d",&x,&y);
                a=gf(x); b=gf(y);
                f[a]=b;
            }
            for(int i=1;i<=n;i++) siz[gf(i)]++;
            for(int i=1;i<=n;i++) ans+=1ll*siz[i]*siz[i];
            printf("%lld
    ",ans);
        }
    }

    point 5:先是发现正是一颗树,又发现偶数组询问等于没有询问,所以猜答案是互相xor的。而单组询问是路径两点路径长。

    #include<bits/stdc++.h>
    #define N 200007
    #define SIZ 24
    #define eho(x) for(int i=head[x];i;i=net[i])
    #define v fall[i]
    using namespace std;
    long long ans,dep[N],anw;
    int T,n,m,x,y,z,f[N][SIZ],a,b,dd[N],fall[N<<1],net[N<<1],tot,head[N],cost[N];
    inline void add(int x,int y,int co) {
        fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=co;
    }
    void dfs(int x,int fa) {
    //    cerr<<x<<endl;
        dd[x]=dd[fa]+1;
        f[x][0]=fa; 
        for (int i=1;i<SIZ;i++) 
         f[x][i]=f[f[x][i-1]][i-1];
        eho(x) if (v!=fa) dep[v]=dep[x]+cost[i],dfs(v,x);
    }
    int pku(int x,int y){
        if (dd[x]<dd[y]) swap(x,y);
        for (int i=SIZ-1;~i;i--) if (dd[f[x][i]]>=dd[y]) x=f[x][i];
        if (x==y) return x;
        for (int i=SIZ-1;~i;i--) 
         if (f[x][i]^f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    signed main () {
    //    T=1;
    //    freopen("test.txt","r",stdin);
        freopen("input5.txt","r",stdin);
        freopen("output5.txt","w",stdout);
        scanf("%d",&T); scanf("%d",&T);
        while (T--) {
    //        memset(f,0,sizeof f);
            memset(head,0,sizeof head); tot=0;
            scanf("%d%d",&n,&m);anw=0;
            for (int i=1;i<n;i++)  {
                scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z);
            }
            dfs(1,0);
            while (m--) {
                scanf("%d%d",&x,&y);
                ans=dep[x]+dep[y]-2*dep[pku(x,y)];
                anw^=ans;
            }
            printf("%lld
    ",anw);
        } return 0;
    }

    point 6:发现输入和point 5一样,不费什么力气就发现了除了单组询问是路径上最短边边权以外和point 5没区别。还有一个坑点就是x==y时的return的不是0,是1987654321

    #include<bits/stdc++.h>
    #define N 200007
    #define SIZ 24
    #define int long long 
    #define eho(x) for(int i=head[x];i;i=net[i])
    #define v fall[i]
    using namespace std;
    long long ans,dep[N],anw;
    int T,n,m,x,y,z,cst[N][SIZ],f[N][SIZ],a,b,dd[N],fall[N<<1],net[N<<1],tot,head[N],cost[N];
    inline void add(int x,int y,int co) {
        fall[++tot]=y; net[tot]=head[x]; head[x]=tot; cost[tot]=co;
    }
    void dfs(int x,int fa) {
    //    cerr<<x<<endl;
        dd[x]=dd[fa]+1;
        f[x][0]=fa; 
        for (int i=1;i<SIZ;i++) 
         f[x][i]=f[f[x][i-1]][i-1],cst[x][i]=min(cst[x][i-1],cst[f[x][i-1]][i-1]);
        eho(x) if (v!=fa) cst[v][0]=cost[i],dfs(v,x);
    }
    int pku(int x,int y){
        if (x==y) return 1987654321;
        int anw=LONG_LONG_MAX;
        if (dd[x]<dd[y]) swap(x,y);
        for (int i=SIZ-1;~i;i--) 
         if (dd[f[x][i]]>=dd[y]) anw=min(anw,cst[x][i]),x=f[x][i];
        if (x==y) return anw;
        for (int i=SIZ-1;~i;i--) 
         if (f[x][i]^f[y][i]) 
          anw=min(anw,cst[x][i]),anw=min(anw,cst[y][i]),x=f[x][i],y=f[y][i];
        return min(anw,min(cst[x][0],cst[y][0]));
    }
    signed main () {
        T=1;
    //    freopen("test.txt","r",stdin);
        freopen("input6.txt","r",stdin);
        freopen("output6.txt","w",stdout);
        scanf("%lld",&T); scanf("%lld",&T);
        while (T--) {
    //        memset(f,0,sizeof f);
            memset(head,0,sizeof head); tot=0;
            scanf("%lld",&n);
            cin>>m;
            anw=0;
            for (int i=1;i<n;i++)  {
                scanf("%lld%lld%lld",&x,&y,&z); 
    //            cin >>x>>y>>z;
                add(x,y,z); add(y,x,z);
    //            cerr<<z<<endl;
            }
            dfs(1,0);
            int xx;
            while (m--) {
                scanf("%lld%lld",&x,&y);
    //            cerr<<x<<' '<<y<<' '<<(xx=pku(x,y))<<endl;
                anw^=pku(x,y);
            }
            printf("%lld
    ",anw);
        } return 0;
    }
    //1987654321
    //1987654321

    point 7:

    通过增量法观察发现是gcd的二维前缀和,一个优雅的反演就可以过了。

    令f(x,y)为要求的答案,有

    f(x,y)* d= D* (x/D)* (y/D)*d

    那么就是卷上一个欧拉函数的事情了。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000007
    int pim[N],tot,t,n,m;
    long long mu[N],ans;
    void pre(){
        mu[1]=1;
        for (int i=2;i<N;i++) {
            if (!mu[i]) mu[i]=i-1,pim[++tot]=i;
            for (int j=1;j<=tot&&pim[j]*i<N;j++) {
                if (i%pim[j]==0) {
                    mu[i*pim[j]]=mu[i]*pim[j]; break;
                }
                mu[i*pim[j]]=mu[i]*(pim[j]-1);
            }
        }
    //    for (int i=1;i<100;i++) cout<<mu[i]<<' ';
        for (int i=1;i<N;i++) mu[i]=mu[i-1]+mu[i];
    }
    signed main () {
        pre();
        freopen("input7.txt","r",stdin);
        freopen("output7.txt","w",stdout);
        scanf("%d%d",&t,&t);
        while (t--) {
            scanf("%d%d",&n,&m);
            if (n>m) swap(n,m);ans=0;
            for (int i=1,last;i<=n;i=last+1) {
                last=min(n/(n/i),m/(m/i));
                ans+=1ll*(n/i)*(m/i)*(mu[last]-mu[i-1]);
            }
            printf("%lld
    ",ans);
        } return 0;
    }

    point 8:观察发现所有的在序列里的值很小,而且答案和序列里具体是哪个值没有关系,只与序列中的其他数是否相等有关,猜一波发现是字符串相关,再想想就知道是求本质不同的字符串。SAM跑一遍就好了。

    #include<bits/stdc++.h>
    #define SIZ 3000007
    using namespace std;
    int t,n,x;
    long long ans;
    struct Node{
        int len,ch[26],fa;
        void clear() {
            fa=len=0; memset(ch,0,sizeof ch);
        }
    }T[SIZ];
    int q,p,last=1,tot=1,np,c[SIZ],id[SIZ];
    long long dp[SIZ],anw;
    inline void ext(int x){
        q=++tot; T[q].clear(); 
        T[q].len=T[last].len+1;
        for (;last&&!T[last].ch[x];last=T[last].fa) T[last].ch[x]=q;
        if (!last) T[q].fa=1; else {
            p=T[last].ch[x];
            if (T[last].len+1==T[p].len) T[q].fa=p;
            else {
                np=++tot; T[np]=T[p]; T[np].len=T[last].len+1;
                T[p].fa=T[q].fa=np;
                for (;last&&T[last].ch[x]==p;last=T[last].fa) T[last].ch[x]=np;
            }
        }
        last=q;
    }
    signed main () {
    //    freopen("test.txt","r",stdin);
        freopen("input8.txt","r",stdin);
        freopen("output8.txt","w",stdout);
        scanf("%d%d",&t,&t);
        while (t--) {
            memset(dp,0,sizeof dp);
            memset(c,0,sizeof c);
            memset(id,0,sizeof id);
            memset(T,0,sizeof T);
            last=tot=1; T[1].clear(); T[0].clear();
            scanf("%d",&n);
            cerr<<n<<"rrsb"<<endl;
            for (int i=1;i<=n;i++) {
             scanf("%d",&x);assert(0<=x&&x<26);
             ext(x); }
            for (int i=1;i<=tot;i++) c[T[i].len]++;
            for (int i=1;i<=n;i++) c[i]+=c[i-1];
            for (int i=1;i<=tot;i++) id[c[T[i].len]--]=i;
            dp[1]=1; ans=0;
            for (int i=0;i<26;i++) if(T[1].ch[i]) dp[T[1].ch[i]]+=dp[1];
            for (int i=2;i<=tot;i++) {
                x=id[i];
                for (int j=0;j<26;j++)
                 if (T[x].ch[j]) dp[T[x].ch[j]]+=dp[x];
                ans+=dp[x];
            }
            printf("%lld
    ",ans);
        } return 0;
    }

    point 9:求最近点对。玄学暴力复杂度竟然是对的。

    #include<bits/stdc++.h>
    #define db double
    #define N 2000007
    #define exp 1e-5
    using namespace std;
    struct Node{
        int x,y;
        inline bool operator <(const Node&X)const &{
           return x<X.x;
        } 
    }a[N];
    db ans;
    #define Mid (l+r>>1)
    inline db que(int x,int y){
        return sqrt(1ll*(a[x].x-a[y].x)*((a[x].x-a[y].x))+1ll*(a[x].y-a[y].y)*(a[x].y-a[y].y));
    }
    void sol(int l,int r){
        if (r-l<=10) {
            for (int i=l;i<=r;i++)
             for (int j=i+1;j<=r;j++)
              ans=min(ans,que(i,j)); return;
        }
        sol(l,Mid); sol(Mid+1,r);
        for (int i=Mid;(a[Mid].x-a[i].x)<ans+exp&&i>=l;i--)
         for (int j=Mid+1;a[j].x-a[Mid].x<ans+exp&&j<=r;j++)
          ans=min(ans,que(i,j));
    }
    int t,n;
    signed main () {
    //    freopen("test.txt","r",stdin);
        freopen("input9.txt","r",stdin);
        freopen("output9.txt","w",stdout);
        scanf("%d%d",&t,&t);
        while (t--) {
            scanf("%d",&n); ans=1e18;
            cerr<<n<<"rrsb
    ";
            for (int i=1;i<=n;i++) 
             scanf("%d%d",&a[i].x,&a[i].y);
            sort(a+1,a+n+1);
            sol(1,n);
            printf("%.3lf
    ",ans);
        } return 0;
    }

    point 10:发现怎么输入都是invalid input!

       那么就输出这个。

    #include<bits/stdc++.h>
    #define db double
    #define N 2000007
    using namespace std;
    struct Node{
        int x,y;
        inline bool operator <(const Node&X)const &{
           return x<X.x;
        } 
    }a[N];
    db ans;
    #define Mid (l+r>>1)
    inline db que(int x,int y){
        return sqrt((a[x].x-a[y].x)*((a[x].x-a[y].x))+(a[x].y-a[y].y)*(a[x].y-a[y].y));
    }
    void sol(int l,int r){
        if (r-l<=10) {
            for (int i=l;i<=r;i++)
             for (int j=i+1;j<=r;j++)
              ans=min(ans,que(i,j)); return;
        }
        sol(l,Mid); sol(Mid+1,r);
        for (int i=Mid;a[Mid].x-a[i].x<ans&&i>=l;i--)
         for (int j=Mid+1;a[j].x-a[Mid].x<ans&&j<=r;j++)
          ans=min(ans,que(i,j));
    }
    int t,n;
    signed main () {
    //    freopen("test.txt","r",stdin);
        freopen("input10.txt","r",stdin);
        freopen("output10.txt","w",stdout);
        scanf("%d%d",&t,&t);
        while (t--) {
            printf("invalid input!
    ");
        } return 0;
    }

    讲道理这题目真毒瘤,不是很难,但我写了一天。

  • 相关阅读:
    Com组件的两种复用方式:包容与集合的区别
    LAPACK/CLAPACK超级无敌算法库
    转:.h头文件 .lib库文件 .dll动态链接库文件关系
    python中类的变量与对象的变量
    重温:Martin Fowler的持续集成
    转:OOD的五个设计原则
    文章资源分享
    代码奔腾 Code Rush
    非ie6、ie7和ie8中iframe在dom中位置改变会引起iframe的指向重新加载
    前端开发利器webStorm
  • 原文地址:https://www.cnblogs.com/rrsb/p/8909346.html
Copyright © 2011-2022 走看看