题意:给定一张n点m边的图,点带点权,定义点覆盖的权值为点权之积,问所有点覆盖的权值之和膜q

n<=36, 1<=a[i]<=1e9,1e8<=q<=1e9

思路:n<=36,考虑middle in the middle分成两个点数接近的点集L和R

对于L,枚举其子集S,判断S能否覆盖所有L内部的边,预处理出所有合法的S的超集的贡献

对于R,枚举其子集T,判断T能否覆盖所有R内部的边,如果可以则可以推出L,R之间在确定R中选T的前提下左边至少需要选点集T’,答案即为T的点权之积*T’的超集的点权积之和

对于判断覆盖和根据T推T'使用了大量位运算加速

需要注意的是如果二进制左右移位可能超边界则要使用ull

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> Pll;
typedef vector<int> VI;
typedef vector<PII> VII;
//typedef pair<ll,ll>P;
#define N 300010
#define M 2000010
#define fi first
#define se second
#define MP make_pair
#define pb push_back
#define pi acos(-1)
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
#define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
#define lowbit(x) x&(-x)
#define Rand (rand()*(1<<16)+rand())
#define id(x) ((x)<=B?(x):m-n/(x)+1)
#define ls p<<1
#define rs p<<1|1 const //ll MOD=1e9+7,inv2=(MOD+1)/2;
double eps=1e-;
int INF=1e9;
int dx[]={-,,,};
int dy[]={,,-,}; ull s[M];
ll a[N],f[N]; int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int isok1(int S,int l,int r)
{
rep(i,l,r)
if(!(S>>i&))
{
ull now=((s[i]<<(-r))>>(-r));
if((now&S)!=now) return ;
}
return ;
} int isok2(int S,int l,int r,int mid)
{
rep(i,l,r)
if(!(S>>i&))
{
ll now=(s[i+mid]>>mid);
if((now&S)!=now) return ;
}
return ;
} int main()
{
int cas=read();
rep(v,,cas)
{
int n=read(),m=read();
ll MOD;
scanf("%I64d",&MOD);
int mid=n/;
rep(i,,n-) scanf("%I64d",&a[i]);
mem(s,);
rep(i,,m)
{
int x=read(),y=read();
x--; y--;
s[x]|=1ll<<y;
s[y]|=1ll<<x;
}
int S1=(<<mid)-;
rep(i,,S1) f[i]=;
rep(i,,S1)
{
ll t=;
rep(j,,mid-)
if(i>>j&) t=t*a[j]%MOD;
if(isok1(i,,mid-)) f[i]=t;
} rep(i,,mid-)
rep(j,,S1)
if(!(j>>i&)) f[j]=(f[j]+f[j^(<<i)])%MOD; int S2=(<<(n-mid))-;
ll ans=;
rep(i,,S2)
{
ll t=;
rep(j,,n-mid-)
if(i>>j&) t=t*a[j+mid]%MOD;
if(isok2(i,,n-mid-,mid))
{
ll base=;
rep(j,,mid-)
{
ull now=(s[j]>>mid);
if((now&i)!=now) base|=<<j;
}
ans=(ans+t*f[base]%MOD)%MOD;
}
}
printf("Case #%d: ",v);
printf("%I64d\n",ans);
}
return ;
}

最新文章

  1. ASP.NET MVC 解析模板生成静态页一(RazorEngine)
  2. centos查看系统cpu个数、核心书、线程数
  3. easyui datagrid中关联combox
  4. 转 C# 给某个方法设定执行超时时间
  5. android 模拟按键事件
  6. .net基础知识
  7. 采集/自动登录啊都可以用这两个方法实现 asp.net
  8. UITableView 小节-备
  9. 【转】安卓Java的虚拟机区别
  10. C#PreviewKeyDown 与KeyDown 区别
  11. PHP——秒数转换为时分秒
  12. REST AND SOAP
  13. bzoj2288 生日礼物 (线段树)
  14. SNF开发平台WinForm之十五-时间轴控件使用-SNF快速开发平台3.3-Spring.Net.Framework
  15. JavaWeb-入门第一课-1.静态web动态web 2.web服务器 3.下载和安装Tomcat-web服务器
  16. js,java,jstl多分隔符分割字符串
  17. OTL翻译(7) -- otl_exception类
  18. gpu和cpu区别
  19. 一文带你了解 Raft 一致性协议的关键点
  20. Node.js 框架对比之 Express VS Koa

热门文章

  1. 操作系统(3)实验相关原理——bootloader启动uCore
  2. 分类属性绘图(seaborn的catplot函数)
  3. 005 gcc 的简单使用
  4. 任务调度之 Quartz
  5. Linux常用命令基础
  6. AcWing 92. 递归实现指数型枚举
  7. KMP字符串匹配 模板 洛谷 P3375
  8. 获取IP地址的几种方法
  9. Proxy does not work using sudo in Debian
  10. django基础知识之认识MVT MVC??