XJOI网上同步训练DAY2 T1
【问题描述】
为了迎接校庆月亮中学操场开始施工。不久后操场下发现了很多古墓这些古墓中有很多宝藏。然而学生们逐渐发现自从操场施工之后学校的运气就开始变得特别不好。后来经过调查发现古墓下有一个太守坟由于操场施工惊动了太守所以学校的运气才会特别不好。
你——月亮中学的学生之一为了拯救学校在梦中和太守进行了沟通。太守说“只要你能解决这个问题我就保佑你们从此事事顺心。你看操场下的古墓中有 个宝藏编号为
到
。现在你必须选择宝藏的一个集合可以不选或者全选。我有两种条件第一种条件有
个每一种条件形如‘如果你选择了宝藏
那么你必须选择宝藏
’第二种条件有
个每一种条件形如‘如果你选择了宝藏
那么你不能选择宝藏
’你需要求出你有多少种选择集合的方式满足所有条件。”
身为月亮中学的学生为了学校你必须回答这个问题。
【输入格式】
从文件treasure.in 中读入数据。
输入的第一行包含三个整数 分别表示物品数第一种条件数第二种条件数。
接下来 行每行两个正整数
表示如果你选择了宝藏
那么你必须选择宝藏
。
接下来 行每行两个正整数
表示如果你选择了宝藏
那么你不能选择宝藏
。
【输出格式】
输出到treasure.out中。
输出一行一个整数表示你有多少种选择集合的方式。
【样例输入1】
5 3 3
1 2
1 4
2 5
3 5
4 5
3 5
【样例输出1】
6
【样例说明1】
用一个整数来表示编号为这个整数的宝藏则6种满足所有条件的宝藏集合为
{},{3},{4},{3,4},{5},{2,5}
而例如{1,4,5}这个集合就是不满足所有条件的它不既满足第一个第一种条件“如果你选择了宝藏1那么你必须选择宝藏2”也不满足第二个第二种条件“如果你选择了宝藏4那么你不能选择宝藏5”。
【样例输入2】
40 0 0
【样例输出2】
1099511627776
【样例说明2】
所有集合都是可行的故答案是 。
【样例输入输出3】
见下发的treasure/treasure.in与treasure/treasure.ans。
【数据规模和约定】
数据点 |
|
|
|
1 |
|
|
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
对于所有数据 。请注意使用64位整型。
思路:本来想要折半枚举,然后再搜索另一半的,没想到TM直接爆搜能过,天理难容啊
1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #define ll long long 7 int a[200005][2],first[200005],tot,next[200005],id[200005],go[200005]; 8 int n,m1,m2; 9 ll ans=0; 10 int read(){ 11 int t=0,f=1;char ch=getchar(); 12 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 14 return t*f; 15 } 16 void dfs(int x,ll sum){ 17 if (x==n+1){ 18 ans+=sum;return; 19 } 20 if (!a[x][0]&&!a[x][1]){ 21 if (first[x]){ 22 a[x][0]++; 23 dfs(x+1,sum); 24 a[x][0]--; 25 a[x][1]++; 26 int i; 27 for (i=first[x];i;i=next[i]){ 28 int pur=go[i]; 29 if (a[pur][!id[i]]) break; 30 if (pur<x&&!a[pur][0]&&!a[pur][1]) sum>>=1; 31 a[pur][id[i]]++; 32 } 33 if (!i) dfs(x+1,sum); 34 a[x][1]--; 35 for (int j=first[x];j!=i;j=next[j]){ 36 int pur=go[j]; 37 a[pur][id[j]]--; 38 } 39 }else dfs(x+1,sum*2LL); 40 }else if (a[x][0]) dfs(x+1,sum); 41 else{ 42 int i; 43 for (i=first[x];i;i=next[i]){ 44 int pur=go[i]; 45 if (a[pur][!id[i]]) break; 46 if (pur<x&&!a[pur][0]&&!a[pur][1]) sum>>=1; 47 a[pur][id[i]]++; 48 } 49 if (!i) dfs(x+1,sum); 50 for (int j=first[x];j!=i;j=next[j]){ 51 int pur=go[j]; 52 a[pur][id[j]]--; 53 } 54 } 55 } 56 int main(){ 57 n=read();m1=read();m2=read(); 58 for (int i=1;i<=m1;i++){ 59 int x=read(),y=read(); 60 tot++; 61 go[tot]=y; 62 id[tot]=1; 63 next[tot]=first[x]; 64 first[x]=tot; 65 } 66 for (int i=1;i<=m2;i++){ 67 int x=read(),y=read(); 68 tot++; 69 go[tot]=y; 70 id[tot]=0; 71 next[tot]=first[x]; 72 first[x]=tot; 73 } 74 dfs(1,(ll)1); 75 printf("%lld\n",ans); 76 }