您的位置:首页 > 其它

SRM694

2016-07-13 00:53 260 查看
250

TrySail

题意:把一个数列分成非空的三组,要求每组异或和的和最大(0≤a[i]≤255,n<=50)

分析:由于异或有减法,所以只要确定两组的异或值,第三组的异或值就确定了,因此可以dp[i][j]代表第一组异或和为i,第二组异或和为j是否可能,注意到取到最大值的三组必然是非空的,因为有a^b<=a+b

500

DistinguishableSetDiv1

题意:问有多少种选择问题的方法,使得n个人对这些问题的回答互不相同,n<=1000,问题总数<=20

分析:对于任意两个人,我们可以处理出一个mask代表这两个人哪些位置相同,显然选择mask和mask的子集都是不满足要求的,因此求个高维前缀和就可以了

1000

SRMDiv0Easy

初始有一个数列,接着有Q次操作,每次给L[i]~R[i]加一个位于X[i]和Y[i]之间的数,最后要求每个数相同,问那个数最大可以是多少

分析:差分后转化为有源汇有上下界的网络流;这种类型的题目做法就是先连t->s流量为无穷,然后求可行流(注意可行流的连边方法);求完之后再在残量网络上求最大流就是答案

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>
#include <queue>
using namespace std;
const int Maxe=10000,Maxn=222,Inf=1e9;
struct E{
int v,c;
E(){}
E(int v,int c):v(v),c(c){}
}e[Maxe];
class SRMDiv0Easy {
public:
int ne;
vector<int>G[Maxn];
int m;
int cnt[Maxn];
int cur[Maxn];
int h[Maxn];
int must[Maxe];
void add(int u,int v,int c){
e[ne]=E(v,c);
G[u].push_back(ne++);
e[ne]=E(u,0);
G[v].push_back(ne++);
}
bool bfs(int st,int ed){
for(int i=0;i<=max(st,ed);i++)h[i]=i==st?0:Inf;
queue<int>q;
q.push(st);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<G[u].size();i++){
int id=G[u][i];
if(e[id].c){
if(h[e[id].v]==Inf){
h[e[id].v]=h[u]+1;
q.push(e[id].v);
}
}
}
}
return h[ed]!=Inf;
}
int dfs(int u,int ed,int a){
if(u==ed||!a)return a;
int ret=0;
for(int &i=cur[u];i<G[u].size();i++){
int id=G[u][i];
int v=e[id].v,c=e[id].c;
if(h[v]==h[u]+1&&c){
int b=dfs(v,ed,min(a,c));
a-=b;
ret+=b;
e[id].c-=b;
e[id^1].c+=b;
}
}
return ret;
}
int solve(int st,int ed){
/*
for(int i=0;i<=tt;i++){
printf("ver%d:\n",i);
for(int j=0;j<G[i].size();j++){
int id=G[i][j];
printf("v=%d c=%d ",e[id].v,e[id].c);
}
puts("");
}
*/
int flow=0;
while(bfs(st,ed)){
memset(cur,0,sizeof(cur));
flow+=dfs(st,ed,Inf);
}
return flow;
}
int get(int N, vector<int> L, vector<int> R, vector<int> X, vector<int> Y) {
int s=N+1,t=N+2,ss=t+1,tt=t+2;
memset(cnt,0,sizeof(cnt));
ne=0;
m=L.size();
for(int i=0;i<=tt;i++)G[i].clear();
for(int i=0;i<m;i++){
add(L[i],R[i]+1,Y[i]-X[i]);
cnt[L[i]]+=X[i];//liu chu
cnt[R[i]+1]-=X[i];
}
int tot=0;
for(int i=0;i<=N;i++){
if(!cnt[i])continue;
if(cnt[i]>0)add(i,tt,cnt[i]),tot+=cnt[i];
else add(ss,i,-cnt[i]);
}
add(s,0,Inf);
int tar=ne-1;
add(N,t,Inf);
add(t,s,Inf);
int ans=solve(ss,tt);
if(ans!=tot)return -1;
solve(s,t);
return e[tar].c;
return 0;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: