zoukankan      html  css  js  c++  java
  • [Codeforces #174] Tutorial

    Link:

    Codeforces #174 传送门

    A:

    求原根的个数,有一条性质是原根个数为$phi(phi(n))$,多了一个不会证的性质

    如果要确定哪些是原根的话还是要枚举,不过对于每个数不用枚举$p$次了

    由于$delta_p(x) | phi(x)$,只要对欧拉函数值的约数枚举即可

    不过此题好像直接$O(p^2)$枚举就行了……

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    typedef double db;
    int p,res;
    
    int main()
    {
        scanf("%d",&p);
        for(int i=1;i<p;i++)
        {
            bool f=1;int t=1;
            for(int j=1;j<=p-2;j++)
            {
                t=(t*i)%p;
                if(t==1) f=0;
            }
            if(t*i%p!=1) f=0;
            res+=f;
        }
        printf("%d",res);
        return 0;
    }
    Problem A

    B:

    简单分类

    #include <bits/stdc++.h>
    
    using namespace std;
    int n,A,I;char s[200005];
    
    int main()
    {
        scanf("%d%s",&n,s+1);
        for(int i=1;i<=n;i++)
            if(s[i]=='A') A++;
            else if(s[i]=='I') I++;
        if(!I) printf("%d",A);
        else if(I==1) printf("1");
        else printf("0");
        return 0;
    }
    Problem B

    C:

    明明写起来很简单的一道题目被我弄复杂了

    考虑维护序列中原来的值和增量

    由于只要求当前最后一个数的增量,因此可以每次仅在增加的最后一个数打上标记

    这样在删除数时将当前末尾的增量向前推就能满足要求

    #include <bits/stdc++.h>
    
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    int n,det[MAXN],dat[MAXN],lst;double sum;
    
    int main()
    {
        scanf("%d",&n);
        dat[1]=0;lst=1;
        while(n--)
        {
            int op,x,y;
            scanf("%d",&op);
            if(op==1) scanf("%d%d",&x,&y),sum+=x*y,det[x]+=y;
            else if(op==2) scanf("%d",&x),sum+=x,dat[++lst]=x;
            else sum-=dat[lst]+det[lst],det[lst-1]+=det[lst],det[lst--]=0;
            printf("%.6lf
    ",sum/lst);
        }
        return 0;
    }
    Problem C

    结果我这个zz用树状数组维护了这个东西,还将一个增量写成了赋值WA了好几次……

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    int n;ll bit[MAXN<<2],dat[MAXN<<2],lst,sum;
    
    void Update(int pos,int x)
    {while(pos<=n) bit[pos]+=x,pos+=pos&(-pos);}
    ll Query(int pos)
    {ll ret=0;while(pos) ret+=bit[pos],pos-=pos&(-pos);return ret;}
    
    int main()
    {
        scanf("%d",&n);
        lst=1;sum=0;
        for(int i=1;i<=n;i++)
        {
            int op,x,y;
            scanf("%d",&op);
            if(op==1)
            {
                scanf("%d%d",&x,&y);
                Update(1,y);Update(x+1,-y);
                dat[1]+=y;dat[x+1]-=y;
                sum+=x*y;
            }
            else if(op==2)
            {
                scanf("%d",&x);
                Update(lst+1,x);Update(lst+2,-x);
                dat[++lst]+=x;dat[lst+1]=-x;
                sum+=x;
            }
            else
            {
                sum-=Query(lst);
                Update(lst+1,-dat[lst+1]);
                Update(lst,dat[lst+1]);
                dat[lst]+=dat[lst+1];dat[lst+1]=0;lst--;
            }
            printf("%.6lf
    ",1.0*sum/lst);
        }
        return 0;
    }
    Problem C

    D:

    可以发现真正的状态数只有$2*n$个,对于每一位只有加/减两种状态

    发现$y$的值就是走过的总距离,这样用$dp[n][2]$记忆化搜索在当前状态走到边界有多远

    每个状态在入栈时打上标记,如果再次走到形成环就是循环了

    这样对于每个$i$就是对应于$dp[i+1][0]$时的解

    注意将边界$dp[1][0/1]$设为-1

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=2e5+10;
    int n,dat[MAXN],vis[MAXN][2];ll dp[MAXN][2];
    
    ll dfs(int x,int d)
    {
        if(x<=0||x>n) return 0;
        if(vis[x][d]==1) return -1;
        if(vis[x][d]==2) return dp[x][d];
        vis[x][d]=1;
        ll dist=d?dfs(x+dat[x],0):dfs(x-dat[x],1);
        vis[x][d]=2;
        if(dist==-1) return dp[x][d]=-1;
        else return dp[x][d]=dist+dat[x];
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++) scanf("%d",&dat[i]);
        vis[1][0]=vis[1][1]=1;
        for(int i=2;i<=n;i++)
        {
            if(!vis[i][0]) dfs(i,0);
            printf("%I64d
    ",dp[i][0]==-1?-1:i+dp[i][0]-1);
        }
        return 0;
    }
    Problem D

    E:

    由于每个点只有一个后继,因此最终图只有环和链

    将环的情况排除后就只剩链了

    对于一条链,一个可行解为$a_1*w_1+a_2*w_2...+a_n*w_n(a_1>a_2>...>a_n)$

    但由于后面的限制条件不能直接背包,考虑将式子变换后消除限制:

    设$d_i=a_i-a_{i-1},suf_i=w_i+w_{i+1}...+w_n$,

    这样式子变为$d_1*suf_1+d_2*suf_2...+d_n*suf_n$

    发现就是一个完全背包,且可以将各个链合并在一起考虑

    但注意,这个背包要求$d_1,d_2...d_{n-1}>0$,否则无法保证条件成立

    也就是原式每个物品的个数要达到${n-1,n-2...2,1,0}$的下限!

    这样就先都取一个,并将其从$t$中减去再跑背包即可

    #include <bits/stdc++.h>
    
    using namespace std;
    #define X first
    #define Y second
    typedef long long ll;
    typedef pair<int,int> P;
    const int MAXN=1e5+10,MOD=1e9+7;
    int n,q,t,x,y,a[MAXN],nxt[MAXN],d[MAXN],dp[MAXN],cnt;
    
    int main()
    {
        scanf("%d%d%d",&n,&q,&t);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=q;i++)
            scanf("%d%d",&x,&y),nxt[x]=y,d[y]++;
        for(int i=1;i<=n&&t>=0;i++)
        {
            if(d[i]) continue;
            int sum=0;//t<0一定要及时退出! 
            for(int j=i;j&&t>=0;j=nxt[j])
            {
                cnt++;
                sum+=a[j];a[j]=sum;
                if(nxt[j]) t-=a[j];
            }
        }
        if(cnt<n||t<0) return puts("0"),0;
        
        dp[0]=1;
        for(int i=1;i<=n;i++)
            for(int j=a[i];j<=t;j++)
                (dp[j]+=dp[j-a[i]])%=MOD;
        printf("%d",dp[t]);
        return 0;
    }
    Problem E

    同时还有一个注意点:$t<0$时要及时退出否则会爆$int$

  • 相关阅读:
    ng2-timesheet, 一个timesheet.js的angular2复制版
    Angular 2 + Electron 开发web和桌面应用
    Xamarin.Forms.Platform.Perspex, Xamarin Forms 的 Perspex(号称下一代WPF) 实现
    Visual Studio Xamarin编译Android项目出错的解决办法
    Salesforce + AngularJS + Bootstrap
    NativeScript 也能开发桌面应用 (nativescript-dotnet-runtime)
    iOS集成丁香园DXY OAuth 登陆 swift代码示例
    WinObjC?这是什么鬼?
    如何禁用Marlin温度保护
    React Native也正式发布了
  • 原文地址:https://www.cnblogs.com/newera/p/9514907.html
Copyright © 2011-2022 走看看