zoukankan      html  css  js  c++  java
  • 【2019.8.13】

    异或求值

    求1到n的异或值,即1^ 2...^n

    50%的数据:$n≤10^6 $ 100%的数据:(1≤n≤10^{18})

    hei水 看了题先挨个挨个列了出来 然后发现各几个就会出现一个0

    后面讲题说,当一个偶数(+1)变成奇数时它们异或的值只会是1(其它位都相同只有最后一位不同)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rg register
    const int N=1000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827;
    ll n,x,ans=0;
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int main(){
    	freopen("xor.in","r",stdin);
    	freopen("xor.out","w",stdout);
    	rd(n);
    	if(!(n+1)%4) return puts("0"),0;
    	x=(n/4)*4;
    	for(x;x<=n;++x) ans^=x;
    	printf("%lld",ans);
        return 0;
    }
    

    染色方案

    有一颗N 个节点的树,节点用1, 2.....N编号。你要给它染色,使得相邻节点的颜色不同。有M种颜色,用1,2.....M编号。每个节点可以染M 种颜色中的若干种,求不同染色方案的数量除以(10^9 + 7)的余数。

    一道树形dp 最后想不出来了 打暴力还打挂了...

    是lsy大佬的思路 考试的时候思路和她是一样的 但考试的时候我脑壳没有转过来弯 并没有想到再来一个数组记录f[u][color]来记录u这个点染成color颜色时的方案数

    当时推的时候意识到当前转移和当前点选颜色有关 but.... emmmmm...

    ans[u]就等于u这个点选择各种颜色的方案数和
    但在l洛谷上会MLE... 可以把col数组和ans数组都压在f数组里qwq

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rg register
    const int N=5000+5,M=5000+5,inf=0x3f3f3f3f,P=1e9+7;
    int n,m,ans[N],col[N][N],f[N][N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{int v,nxt;}e[N<<1];
    void add(int u,int v){
        e[++tot]=(edge){v,head[u]},head[u]=tot;
    }
    
    void dfs(int u,int fa){
    	for(int i=head[u],v;i;i=e[i].nxt){
    		v=e[i].v;
    		if(v==fa) continue;
    		dfs(v,u);
    		for(int j=1;j<=col[u][0];++j)
    		f[u][col[u][j]]=((ll)f[u][col[u][j]]*(ans[v]-f[v][col[u][j]]+P))%P;
    	}
    	for(int i=1;i<=col[u][0];++i) ans[u]=(ans[u]+f[u][col[u][i]])%P;
    }
    
    int main(){
    	freopen("color.in","r",stdin);
    	freopen("color.out","w",stdout);
    	rd(n),rd(m);
    	for(int i=1,k;i<=n;++i){
    		rd(k),col[i][0]=k;
    		for(int j=1,x;j<=k;++j) rd(x),col[i][j]=x,f[i][x]=1;
    	}
    	for(int i=1,u,v;i<n;++i)
    		rd(u),rd(v),add(u,v),add(v,u);
    	dfs(1,0);
    	printf("%d",ans[1]);
        return 0;
    }
    

    新三国争霸

    PP 特别喜欢玩即时战略类游戏,但他觉得那些游戏都有美中不足的地方。灾害总不降临道路,而只降临城市,而且道路不能被占领,没有保护粮草的真实性。于是他就研发了《新三国争霸》。

    在这款游戏中,加入灾害对道路的影响(也就是一旦道路W[i,j]受到了灾害的影响,那么在一定时间内,这条路将不能通过)和道路的占领权(对于一条道路W[i,j],至少需要K[i,j]个士兵才能守住)。

    PP可真是高手,不一会,就攻下了N-1座城市,加上原来的就有N座城市了,但他忽略了一点……那就是防守同样重要,不过现在还来的及。因为才打完仗所以很多城市都需要建设,PP估算了一下,大概需要T天。他现在无暇分身进攻了,只好在这T天内好好的搞建设了。所以他要派士兵占领一些道路,以确保任何两个城市之间都有路(不然敌人就要分而攻之了,是很危险的)。士兵可不是白干活的,每个士兵每天都要吃掉V的军粮。因为有灾害,所以方案可能有变化(每改变一次就需要K的军粮,初始方案也需要K的军粮)。

    因为游戏是PP编的,所以他知道什么时候有灾害。PP可是一个很节约的人,他希望这T天在道路的防守上花最少的军粮。

    对于所有数据:(N<=300,M<=5000 ,T<=50,P<=8000)

    和[ZJOI2006]物流运输 很像(或者一样?) 因为之前做过物流运输所以这题就按的我做物流运输的方法

    枚举时间段 算出各个时间段只走一种方案所需的花费 最后dp转移

    我把这段时间只要该路有一天不能走就全封掉(虽然我不知道为什么 但是对答案不影响 因为(T^2)枚举了各个时间段)

    考试的时候枚举该时间段内封掉的路我用的N^2枚举i能否到j 而N^2就已经到9w了QAQ 后面我看 直接枚举m条边不就好了?! 成功被自己sb到...

    标程有一个小技巧(?) 判断这个时间段是否被封可以用前缀和

    先在读入时将其读入第k天u到v不能走lim[u][v][k]=1 然后算一遍前缀和 判断u到v在l~r这段时间有没有被锁就判断lim[u][v][l]是否等于lim[u][v][r] (虽然在我的方法里没啥用和我的40分一样... 但是很巧妙就对了)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define rg register
    #define Max(x,y) ((x)>(y)?(x):(y))
    #define Min(x,y) ((x)>(y)?(y):(x))
    const int N=300+5,M=5000+5,inf=0x3f3f3f3f,P=19650827;
    int n,m,t,vv,k,p,f[N],val[60][60],ans[60][60];
    bool lim[N][N][60],can[N][N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    int head[N],tot=0;
    struct edge{
        int u,v,w;
        bool operator<(const edge&A)const{return w<A.w;}
    }e[M];
    
    int sum,cnt;
    int find(int x) {return f[x]==x?x:f[x]=find(f[x]);}
    void kruskal(){
        for(rg int i=1;i<=n;++i) f[i]=i;
        for(rg int i=1,u,v;i<=m;++i){
            u=e[i].u,v=e[i].v;
            if(cnt>=n-1) return;
            if(!can[u][v]&&find(u)!=find(v)){
                f[f[u]]=f[v];
                sum+=e[i].w,++cnt;
            }
        }
    }
    
    int main(){
        freopen("three.in","r",stdin);
        freopen("three.out","w",stdout);
        rd(n),rd(m),rd(t),rd(vv),rd(k);
        for(int i=1,u,v,w;i<=m;++i)
        rd(e[i].u),rd(e[i].v),rd(e[i].w);
        sort(e+1,e+m+1);
        rd(p);
        for(int i=1,x,y,l,r;i<=p;++i){
            rd(x),rd(y),rd(l),rd(r);
            for(int j=l;j<=r;++j) lim[x][y][j]=lim[y][x][j]=1;
        }
        for(int r=1;r<=t;++r)
        for(int l=1;l<=r;++l){
            memset(can,0,sizeof(can));
            for(int i=1,u,v;i<=m;++i)
            for(int k=l;k<=r;++k){
                u=e[i].u,v=e[i].v;
                if(!can[u][v]&&lim[u][v][k]) can[u][v]=can[v][u]=1;
            }
            sum=cnt=0,kruskal();
            if(cnt<n-1) val[l][r]=inf;
            else val[l][r]=sum*(r-l+1)*vv;
        }
        memset(ans,inf,sizeof(ans));
        for(int i=1;i<=t;++i) ans[1][i]=val[1][i];
        for(int i=1;i<=t;++i)
            for(int j=1;j<i;++j) ans[1][i]=Min(ans[1][i],ans[1][j]+val[j+1][i]+k);
        printf("%d",ans[1][t]+k);
        return 0;
    }
    

    summary

    这次感觉难度还行?只是我太弱了

    • 遇到类似的题不能盲目自信 还是要冷静分析
    • 加强树形dp吧...
    • 暴力分要拿够!
  • 相关阅读:
    问题解决:FFmpeg视频编解码库,无法解析的外部信号
    2016,最值得市场营销人员关注的数字营销策略
    排序
    hdu 1385 Minimum Transport Cost(floyd &amp;&amp; 记录路径)
    使用Android SwipeRefreshLayout了解Android的嵌套滑动机制
    搜索引擎keyword智能提示的一种实现
    维度模型数据仓库基础对象概念一览
    vs2015编译zlib1.2.8
    关系数据库关系的完整性
    XMPPFrameWork IOS 开发(一)xmpp简介
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11348578.html
Copyright © 2011-2022 走看看