Choice is an illusion created between those with power and those without.
《The Matrix》
炒鸡喜欢《The Matrix》,追几遍都超酷,深思极恐的乐趣,以及人类法则,规则本身,程序设计(最后这个是乱加的)的思考。
所以回到题目
T3
题目大意
度度熊有一张n个点m条边的**无向图**,第i个点的点权为vi。
如果图上存在一条**路径**使得点i可以走到点j,则称i,j是**带劲**的,记f(i,j)=1;否则f(i,j)=0。显然有f(i,j)=f(j,i)。
度度熊想知道求出:
∑i(1<=i<=n)∑j(i+1<=j<=n) f(i,j)×max(vi,vj)×(vi&vj)
其中&是C++中的and位运算符,如1&3=1, 2&3=2。
请将答案对1e9+7取模后输出。
两个关键点
首先判断无向图中两个点是否可以连通
两种方法:1、对点进行dfs 感觉较下一种写起来有点复杂
2、并查集维护(记录每个点在哪个集中即可,具体可看代码)(注意并查集只能针对无向图而言,不针对有向图)
小拓展:判断有向图中两个点是否可以连通
tarjan 只适用于强连通(a能到b b也能到a)
单连通 又是怎样的? 那就传递闭包吧(还没有找到更好的方法)
处理这个式子 针对max要高效处理 可以排序
根据&二进制特性 dp处理比这个数小的数中的每一位0/1的数量个数 一位位考虑,统一加即可。
T4
题意:
度度熊有k(k≥2)个序列s1,s2,..,sk,每个序列的长度均为n,且序列中每个数均是1到n之间某个整数,请问这k个串有多少个长度大于0的**公共子序列**?
**解释**:在每个序列中都选出一些位置,并将这些位置对应的字符**顺次**拼接起来,当它们都相等时,称其为公共子序列。
答案可能很大,请对109+7取模。
就是求不同公共序列的个数(位置不同也算不同)
注意随机数据的特性,不会出现极端条件,
预处理状态(k行每行字母相同时位置序列),
然后判断状态与状态间是否可转移(及对于状态k行中每行的i的字母位置
#include
#include
#include
#include
#include
#include
using namespace std;
const long long mod=1e9+7;
long long t[100],x,y,n,m,T,x1,y11,ans,a[101005],root[101005],f[33];
vector w[101005];
int find(int x) {if (root[x]==x) return x;else return root[x]=find(root[x]);}
int main()
{ cin>>T;
while (T--)
{ scanf("%lld%lld",&n,&m);
for (int i=1;i<=n;i++)
scanf("%lld",&a[i]),root[i]=i;
for (int i=1;i<=m;i++)
{ scanf("%lld%lld",&x1,&y11);
root[find(x1)]=find(y11);}
ans=0;
for (int i=1;i<=n;i++) w[i].clear();
for (int i=1;i<=n;i++)
{ w[find(i)].push_back(a[i]);}
for (int i=1;i<=n;i++)
{ if (w[i].size()>1)
{ memset(f,0,sizeof(f));
sort(w[i].begin(),w[i].end());
for (int j=0;j>l)&1)
{ ans=(ans+(f[l]*(1ll<
//自己代码找不到,贴一发和我写的类似的,感谢bestfy
#include
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
#define inf 1000000001
#define y1 y1___
using namespace std;
#define N 3005
#define mod 1000000007
int n,m,cnt,a[6][N],now[6],h[N][6],q[N],f[N],ans;vector p[6][N];
void dfs(int x,int y){
if (x>m){
memcpy(h[++cnt],now,sizeof(now));
return;
}
rep (i,0,(int)p[x][y].size()-1) now[x]=p[x][y][i],dfs(x+1,y);
}
bool cmp(int x,int y){return h[x][1]=h[y][i]) return 0;return 1;}
int Main(){
scanf("%d%d",&m,&n);
rep (i,1,m){
rep (j,1,n) p[i][j].clear();
rep (j,1,n) scanf("%d",&a[i][j]),p[i][a[i][j]].push_back(j);
}
cnt=0;
rep (i,1,n) dfs(1,i);
rep (i,1,cnt) q[i]=i;
sort(&q[1],&q[cnt+1],cmp);ans=0;
rep (i,1,cnt){
f[q[i]]=1;
rep (j,1,i-1)
if (smaller(q[j],q[i])) f[q[i]]=(f[q[i]]+f[q[j]])%mod;
ans=(ans+f[q[i]])%mod;
}
printf("%d\n",ans);
return 0;
}
int main(){
int T;scanf("%d",&T);while (T--) Main();
return 0;
}
//预处理+dp