T1
树形dp
dp[i][j]表示以i为子树,j个黑点
每次向上枚举更新即可
复杂度O(n^2)考场上sb了被卡常,50滚粗
T2树链剖分,不说了
T3博弈论
首先搜索打表找规律
发现n/i一定时,sg一定
然后分块大法好
set
vfk未来的论文题,刚好在考前一天看过还给bzoj写了spj。。。。
http://www.cnblogs.com/gromah/p/4642344.html 快去围观大神的博客
悲剧又被卡常= =60
str
好像是矩乘来着?蒟蒻表示吓傻了
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #define ll long long #define inf 100000000 using namespace std; inline void splay(ll &v){ v=0;char c=0;ll p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } struct Edge{ ll to,next,len; }edge[4010]; ll dp[2005][2005]; ll size[2005]; ll n,k; ll first[4010],Size; void addedge(ll x,ll y,ll z){ Size++; edge[Size].to=y; edge[Size].len=z; edge[Size].next=first[x]; first[x]=Size; } void dfs(ll now,ll fa){ size[now]=1;dp[now][0]=dp[now][1]=0; for(ll u=first[now];u;u=edge[u].next){ if(edge[u].to==fa)continue; dfs(edge[u].to,now);size[now]+=size[edge[u].to]; for(ll i=size[now];i>=0;i--){ for(ll j=0;j<=size[edge[u].to]&&j<=i&&j<=k;j++){ dp[now][i]=max(dp[now][i],dp[now][i-j]+dp[edge[u].to][j]+(j*(k-j)+(size[edge[u].to]-j)*(n-k-(size[edge[u].to]-j)))*edge[u].len); } } } } int main(){ freopen("t1.in","r",stdin); freopen("t1.out","w",stdout); splay(n),splay(k); for(ll i=1;i<n;i++){ ll x,y,z; splay(x),splay(y),splay(z); addedge(x,y,z),addedge(y,x,z); } memset(dp,-63,sizeof dp); dfs(1,0); cout<<dp[1][k]<<endl; }
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #define foreach(u,now) for(int u=first[now];u;u=edge[u].next) #define ll long long #define inf 1000000000 #define mod 1000000000 using namespace std; inline void R(int &v) { v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } int n,m,cnt; int last[100005]; int id,pos[100005],mx[100005],v[100005]; int bl[100005],size[100005],fa[100005]; ll tag[400005],sum[400005]; struct Edge { int to,next; }edge[200005]; void addedge(int u,int v) { edge[++cnt]=(Edge){v,last[u]};last[u]=cnt; edge[++cnt]=(Edge){u,last[v]};last[v]=cnt; } void dfs(int x) { size[x]=1; for(int i=last[x];i;i=edge[i].next) if(edge[i].to!=fa[x]) { fa[edge[i].to]=x; dfs(edge[i].to); size[x]+=size[edge[i].to]; mx[x]=max(mx[x],mx[edge[i].to]); } } void dfs2(int x,int cha) { bl[x]=cha;pos[x]=mx[x]=++id; int k=0; for(int i=last[x];i;i=edge[i].next) if(edge[i].to!=fa[x]&&size[edge[i].to]>size[k]) k=edge[i].to; if(k)dfs2(k,cha),mx[x]=max(mx[x],mx[k]); for(int i=last[x];i;i=edge[i].next) if(edge[i].to!=fa[x]&&edge[i].to!=k) dfs2(edge[i].to,edge[i].to),mx[x]=max(mx[x],mx[edge[i].to]); } void pushdown(int l,int r,int k) { if(l==r)return; int mid=(l+r)>>1;ll t=tag[k];tag[k]=0; tag[k<<1]+=t;tag[k<<1|1]+=t; sum[k<<1]+=t*(mid-l+1); sum[k<<1|1]+=t*(r-mid); } void add(int k,int l,int r,int x,int y,ll val) { if(tag[k])pushdown(l,r,k); if(l==x&&y==r){tag[k]+=val;sum[k]+=(r-l+1)*val;return;} int mid=(l+r)>>1; if(x<=mid)add(k<<1,l,mid,x,min(mid,y),val); if(y>=mid+1)add(k<<1|1,mid+1,r,max(mid+1,x),y,val); sum[k]=sum[k<<1]+sum[k<<1|1]; } ll query(int k,int l,int r,int x,int y) { if(tag[k])pushdown(l,r,k); if(l==x&&y==r)return sum[k]; int mid=(l+r)>>1; ll ans=0; if(x<=mid)ans+=query(k<<1,l,mid,x,min(mid,y)); if(y>=mid+1)ans+=query(k<<1|1,mid+1,r,max(mid+1,x),y); return ans; } ll query(int x) { ll ans=0; while(bl[x]!=1) { ans+=query(1,1,n,pos[bl[x]],pos[x]); x=fa[bl[x]]; } ans+=query(1,1,n,1,pos[x]); return ans; } int main() { freopen("xxx.in","r",stdin); freopen("xxx.out","w",stdout); R(n),R(m); for(int i=1;i<=n;i++)R(v[i]); for(int i=1;i<n;i++) { int u,v; R(u),R(v); addedge(u,v); } dfs(1); dfs2(1,1); for(int i=1;i<=n;i++)add(1,1,n,pos[i],pos[i],v[i]); int opt,x,a; while(m--) { R(opt);R(x); if(opt==1)R(a),add(1,1,n,pos[x],pos[x],a); if(opt==2)R(a),add(1,1,n,pos[x],mx[x],a); if(opt==3)printf("%lld\n",query(x)); } return 0; }
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> using namespace std; #define ld long double #define db double #define lowbit(i) ((i)&(-(i))) #define eps (1e-9) ld a[1148576]; ld s[1148576]; int main(){ freopen("set.in","r",stdin); freopen("set.out","w",stdout); int n;cin>>n;s[0]=1; for(int i=0;i<(1<<n);i++){ db x;scanf("%lf",&x);a[i]=(ld)x; } int can=0; for(int i=0;i<(1<<n);i++){ if(a[i]>eps)can|=i; } if(can!=(1<<n)-1)puts("INF"),exit(0); for(int i=1;i<(1<<n);i<<=1){ for(int j=0;j<=(1<<n);j++){ if(!(i&j))a[i+j]+=a[j]; } } ld ans=0; for(int i=0;i<(1<<n)-1;i++){ if(i)s[i]=-s[i-lowbit(i)];//1的个数,在第几层 ans+=s[i]/(1-a[i]); } if(ans<0)ans=-ans; printf("%0.9f",(db)ans); }