2018.3.8

bzoj3687简单题

小呆开始研究集合论了,他提出了关于一个数集四个问题:

1.子集的异或和的算术和。

2.子集的异或和的异或和。

3.子集的算术和的算术和。

4.子集的算术和的异或和。

目前为止,小呆已经解决了前三个问题,还剩下最后一个问题还没有解决,他决定把这个问题交给你,未来的集训队队员来实现。

输入格式
第一行,一个整数n。

第二行,n个正整数,表示a1,a2….,。

输出格式
一行,包含一个整数,表示所有子集和的异或和。

样例数据
input

2
1 3
output

6
数据规模与约定
【样例解释】

6=1 异或 3 异或 (1+3)

【数据规模与约定】 数据分为A,B,C 三类。 A 类数据(20%) 保证:ai > 0,1<=n<=10。

B 类数据(40%) 保证:ai > 0,1<=n<=1000,Σai<=10000。

C 类数据(40%) 保证:ai > 0,1<=n<=1000,Σai<=2000000。

另外,不保证集合中的数满足互异性,即有可能出现ai = aj 且i ̸= j。

时间限制:1s1s
空间限制:256MB

昨天局限在了状态压缩的观念….想着用二进制数表示某个数是否出现过…..忽略了bitset的强大。能开很大很大很大。那么就可以直接开一个2000000的bitset,每一位都代表某个数是否存在。初值f[0]为1,每次将f异或上f<

#include<bits/stdc++.h>
using namespace std;
int n,m;
int read() { 
    bool flag=true; 
    int num=0;char c=getchar(); 
    for(;c<'0'||c>'9';c=getchar())if(c=='-') flag=false; 
    for(;c>='0'&&c<='9';c=getchar()) 
    num=(num<<3)+(num<<1)+c-48; 
    if(flag) return num; 
     else return -num; 
}
bitset<2010000>f;
int main(){
    n = read();
    int sum = 0;
    f[0] = 1;
    for(int i = 1 ; i <= n ;++i){
        int x = read();
        sum += x;
        f = f ^ ( f << x );
     }
    int ans=0;
    for(int i = 0;i <= sum;++i)
      if(f[i]) ans ^= i; 
    printf("%d",ans);
    return 0;
}

代码非常短。
2、

[Usaco2015 Jan silver]Meeting Time

题目描述
Bessie and her sister Elsie want to travel from the barn to their favorite field, such that they leave at exactly the same time from the barn, and also arrive at exactly the same time at their favorite field. The farm is a collection of N fields (1 <= N <= 100) numbered 1..N, where field 1 contains the barn and field N is the favorite field. The farm is built on the side of a hill, with field X being higher in elevation than field Y if X < Y. An assortment of M paths connect pairs of fields. However, since each path is rather steep, it can only be followed in a downhill direction. For example, a path connecting field 5 with field 8 could be followed in the 5 -> 8 direction but not the other way, since this would be uphill. Each pair of fields is connected by at most one path, so M <= N(N-1)/2. It might take Bessie and Elsie different amounts of time to follow a path; for example, Bessie might take 10 units of time, and Elsie 20. Moreover, Bessie and Elsie only consume time when traveling on paths between fields – since they are in a hurry, they always travel through a field in essentially zero time, never waiting around anywhere. Please help determine the shortest amount of time Bessie and Elsie must take in order to reach their favorite field at exactly the same moment.

给定一张拓扑图,每条边有两个边权,求两条1到n的路径,第一条路径用边权1,第二条路径用边权2,要求两条路径长度相等且最短

输入格式
The first input line contains N and M, separated by a space.

Each of the following M lines describes a path using four integers A B C D,

where A and B (with A < B) are the fields connected by the path,

C is the time required for Bessie to follow the path, and D is the time required for Elsie to follow the path.

Both C and D are in the range 1..100.

输出格式
A single integer, giving the minimum time required for Bessie and Elsie to travel to their favorite field and arrive at the same moment. If this is impossible, or if there is no way for Bessie or Elsie to reach the favorite field at all, output the word IMPOSSIBLE on a single line.

样例数据
input

3 3
1 3 1 2
1 2 1 2
2 3 1 2
output

2
样例解释
Bessie is twice as fast as Elsie on each path, but if Bessie takes the path 1->2->3 and Elsie takes the path 1->3 they will arrive at the same time.

数据规模与约定
保证a,b≤109a,b≤109。

时间限制:1s1s
空间限制:256MB

这道题看到这组数据就放心了。 最大的路径也不会超过10000。
分开搜索,把可能的路径长度存入两个bieset就行了

#include<bits/stdc++.h>
using namespace std;
int n,m,t,linkk[110],M;
bool f[110][10100];
bool vis[110];
struct node{
    int n,y,v1,v2;
}e[5100];
int read() { 
    bool flag = true; int num = 0;char c = getchar(); 
    for(;c < '0' || c > '9';c = getchar())if(c == '-') flag = false; 
    for(;c >= '0' && c <= '9';c = getchar()) num = ( num << 3 ) + ( num << 1 ) + c - 48; 
    if(flag) return num;  else return -num; 
}
bitset<10009>a,b;
void init(){
    n = read();m = read();
    for(int i = 1;i <= m;++i){
        int a = read(),b = read(),c = read(),d = read();
        e[++t].n = linkk[a];
        e[t].y = b;
        e[t].v1 = c;
        e[t].v2 = d;
        linkk[a] = t;
    }
    return;
}
void dfs1(int x,int v){
    if(f[x][v]) return;
    f[x][v] = true;
    vis[x] = true;
    if(x == n) {b[v] = 1;M = max( M , v  );return;} 
    for(int i = linkk[x];i;i = e[i].n)
     if(!vis[e[i].y])
      dfs1(e[i].y,v + e[i].v1),vis[ e[i].y ] = false;
    return;
}
void dfs2(int x,int v){
    if(f[x][v]) return;
    f[x][v] = true;
    vis[x] = true;
    if(x == n) {a[v] = 1;M = max( M , v  );return;} 
    for(int i = linkk[x];i;i = e[i].n)
     if(!vis[e[i].y])
      dfs2(e[i].y,v + e[i].v2),vis[ e[i].y ] = false;
    return;
}
int main(){
    init();
    dfs1(1,0);
    memset(f,0,sizeof(f));
    vis[1]=false;
    dfs2(1,0);
    for(int i=1;i<=M;++i)
     if(a[i] && b[i]) {printf("%d",i);return 0;} 
    printf("IMPOSSIBLE");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1035719430/article/details/79489138