T1

有一棵点数为N的树,树边有边权。给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。N,K<=2000

这个树形dp不是很好想...因为贡献十分混乱...

题解十分神奇...我们记f[i][j]为i的子树有j个黑点的最大权值。

注意直接dp十分蛋疼,这个权值指的是,这个子树内部的贡献,以及i与父亲之间的边对答案的贡献(比如这条边对黑点对距离和的贡献就是子树内部的黑点数*子树外部的黑点数*这条边的权值)。

这个转移就是正常的子树合并...似乎子树合并的题目这个trick十分有用啊...

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define cif(x) if(x) continue
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define TIMER cerr<<clock()<<"ms\n"
#define gmax(a,b) if((a)<(b)) (a)=(b);
#define gmin(a,b) if((a)>(b)) (a)=(b);
#define SZ 666666
Edgc
int n,k,sz[SZ];
ll dp[2333][2333],tmp[2333];
void dfs(int x,int f=0,int fv=0)
{
int cs=1;
for es(x,e)
{
int b=vb[e]; cif(b==f);
dfs(b,x,vc[e]);
int cc=cs+sz[b];
for(int i=0;i<=min(cc,k);i++) tmp[i]=0;
for(int i=0;i<=cs&&i<=k;i++)
{
for(int j=0;j<=sz[b]&&j<=k;j++)
{
if(i+j>k) continue;
gmax(tmp[i+j],dp[x][i]+dp[b][j]);
}
}
for(int i=0;i<=min(cc,k);i++) dp[x][i]=tmp[i];
cs=cc;
}
sz[x]=cs;
for(int i=0;i<=cs&&i<=k;i++)
{
if(cs+(k-i)>n)
{
dp[x][i]=-2147400000; continue;
}
//xblack=i xwhite=cs-i
//wblack=k-i wwhite=n-cs-(k-i)
dp[x][i]+=(ll)i*(k-i)*fv;
dp[x][i]+=(ll)(cs-i)*(n-cs-(k-i))*fv;
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
adde(a,b,c);
}
dfs(1);
cout<<dp[1][k]<<"\n";
}

T2

链剖裸题就不说了...

似乎有两遍dfs序的做法写了写没调出来...

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define SZ 666666
typedef long long ll;
ll a1[210001],a2[210001];
ll qzh(int r)
{
ll s1=0,s2=0;
for(int i=r;i>=1;i-=i&-i) s1+=a1[i], s2+=a2[i];
return (r+1)*s1-s2;
}
ll sum(int l,int r)
{
return qzh(r)-qzh(l-1);
}
void edt(ll a,ll s1)
{
ll s2=a*s1;
for(;a<=210000;a+=a&-a) a1[a]+=s1, a2[a]+=s2;
}
void edt(int l,int r,ll a) {edt(l,a); edt(r+1,-a);}
namespace lct
{
#define SZ 666666
int n,S=0,ns[SZ],fs[SZ],ss[SZ],fa[SZ],siz[SZ],ws[SZ],dep[SZ],fe[SZ],top[SZ],X=0,ls[SZ];
void ad_de(int x,int y)
{
++S; ns[S]=fs[x]; fs[x]=S; ss[S]=y;
}
void adde(int x,int y) {ad_de(x,y); ad_de(y,x);}
void dfs1(int cur)
{
siz[cur]=1; ws[cur]=0;
int csc=-233;
for(int x=fs[cur];x;x=ns[x])
{
int c=ss[x];
if(c==fa[cur]) continue;
fa[c]=cur;
dep[c]=dep[cur]+1;
dfs1(c);
if(siz[c]>csc) csc=siz[c], ws[cur]=c;
siz[cur]+=siz[c];
}
}
void dfs2(int cur,int tp)
{
fe[cur]=++X; top[cur]=tp;
if(ws[cur]) dfs2(ws[cur],tp);
for(int x=fs[cur];x;x=ns[x])
{
int c=ss[x];
if(c!=ws[cur]&&c!=fa[cur]) dfs2(c,c);
}
ls[cur]=X;
}
void s1(int cur,int V)
{
edt(fe[cur],ls[cur],V);
}
ll s2(int x)
{
int u=1,v=x; ll ans=0;
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2]) swap(f1,f2), swap(u,v);
ans+=sum(fe[f1],fe[u]);
u=fa[f1]; f1=top[u];
}
if(dep[u]>dep[v]) swap(u,v);
ans+=sum(fe[u],fe[v]);
return ans;
}
}
int qq[233333];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",qq+i);
}
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
lct::adde(a,b);
}
lct::dfs1(1); lct::dfs2(1,1);
for(int i=1;i<=n;i++) edt(lct::fe[i],lct::fe[i],qq[i]);
for(int i=1;i<=m;i++)
{
int p; scanf("%d",&p);
if(p==1)
{
int x,a; scanf("%d%d",&x,&a);
edt(lct::fe[x],lct::fe[x],a);
}
else if(p==2)
{
int x,a; scanf("%d%d",&x,&a);
lct::s1(x,a);
}
else
{
int x; scanf("%d",&x);
printf("%lld\n",lct::s2(x));
}
}
}

T3

这个sg题真是感人至深啊...

参考链接 http://blog.csdn.net/lych_cys/article/details/50896005

首先我们可以发现问题可以转化为存在若干白点,然后将所有点翻转成黑点,先全部翻转的为胜。因为如果从黑点开始翻转后手可以翻过来...

那么我们就可以假装只有一个白点,然后把sg值异或在一起。

算一下sg,可以发现一个白点i可以转移到2i,2i、3i,2i、3i、4i...

那就是说sg[i]=mex{sg[i]^sg[2i],sg[i]^sg[2i]^sg[3i]...}

经过仔细观察(归纳证明)可以发现sg[i]只与n/i有关。

那么我们就可以暴力像莫比乌斯反演那样做,预处理时大模拟显然是不超过O(n)的,对于<=根号n的我们直接存,>根号n的就用n除一下再存。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#ifdef LOCAL
#define TIMER cerr<<clock()<<"ms\n"
#else
#define TIMER
#endif
#define SZ 666666
int nxt(int x,int n)
{
if(x==n) return n+1;
return n/(n/(x+1)); //end
}
int n,k,sg[SZ],fsg[SZ],Q,tmp[SZ];
int main()
{
scanf("%d%d",&n,&k); Q=sqrt(n)+1;
for(int i=1;i<=n;i=nxt(i,n))
{
int cur=0; tmp[cur]=i;
for(int j=2;j<=i;j=nxt(j,i))
{
int t=i/j,p=(t<=Q)?sg[t]:fsg[n/t];
tmp[cur^p]=i;
if((i/t-i/(t+1))&1) cur^=p;
}
cur=0;
while(tmp[cur]==i) ++cur;
if(i<=Q) sg[i]=cur;
else fsg[n/i]=cur;
}
while(k--)
{
int ans=0,m;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int x; scanf("%d",&x);
int t=n/x; ans^=(t<=Q)?sg[t]:fsg[n/t];
}
if(ans) puts("Yes"); else puts("No");
}
}

HAOI2015 泛做的更多相关文章

  1. codeforces泛做..

    前面说点什么.. 为了完成日常积累,傻逼呵呵的我决定来一发codeforces 挑水题 泛做.. 嗯对,就是泛做.. 主要就是把codeforces Div.1的ABCD都尝试一下吧0.0.. 挖坑0 ...

  2. 学记笔记 $\times$ 巩固 · 期望泛做$Junior$

    最近泛做了期望的相关题目,大概\(Luogu\)上提供的比较简单的题都做了吧\(233\) 好吧其实是好几天之前做的了,不过因为太颓废一直没有整理-- \(Task1\) 期望的定义 在概率论和统计学 ...

  3. 历年NOIP水题泛做

    快noip了就乱做一下历年的noip题目咯.. noip2014 飞扬的小鸟 其实这道题并不是很难,但是就有点难搞 听说男神错了一个小时.. 就是$f_{i,j}$表示在第$i$个位置高度为$j$的时 ...

  4. LCT裸题泛做

    ①洞穴勘测 bzoj2049 题意:由若干个操作,每次加入/删除两点间的一条边,询问某两点是否连通.保证任意时刻图都是一个森林.(两点之间至多只有一条路径) 这就是个link+cut+find roo ...

  5. 基尔霍夫矩阵题目泛做(AD第二轮)

    题目1: SPOJ 2832 题目大意: 求一个矩阵行列式模一个数P后的值.p不一定是质数. 算法讨论: 因为有除法而且p不一定是质数,不一定有逆元,所以我们用辗转相除法. #include < ...

  6. 后缀自动机/回文自动机/AC自动机/序列自动机----各种自动机(自冻鸡) 题目泛做

    题目1 BZOJ 3676 APIO2014 回文串 算法讨论: cnt表示回文自动机上每个结点回文串出现的次数.这是回文自动机的定义考查题. #include <cstdlib> #in ...

  7. FFT与多项式、生成函数题目泛做

    题目1 COGS 很强的乘法问题 高精度乘法用FFT加速 #include <cstdlib> #include <iostream> #include <algorit ...

  8. 二维计算几何基础题目泛做(SYX第一轮)

    题目1: POJ 2318 TOYS 题目大意: 给一个有n个挡板的盒子,从左到右空格编号为0...n.有好多玩具,问每个玩具在哪个空格里面. 算法讨论: 直接叉积判断就可以.注意在盒子的边界上面也算 ...

  9. 生成树题目泛做(AD第二轮)

    题目1: NOI2014 魔法森林 LCT维护MST.解题报告见LOFTER #include <cstdio> #include <iostream> #include &l ...

随机推荐

  1. 变通实现微服务的per request以提高IO效率

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  2. 通过Laravel 初识Vue.js

    最近也在学习laravel的框, 因为之前学过tp框架, 都说laravel是最优雅的框架,所以开学后忍不住去试试这个在国外已经火的不要不要的框架. 总的来说,对于学习完tp框架后,我觉得tp毕竟是中 ...

  3. CSS3与页面布局学习笔记(八)——浏览器兼容性问题与前端性能优化方案

    一.浏览器兼容 1.1.概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题.不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运 ...

  4. iOS下Audio自动播放(Autoplay)音乐

    前几天做了一个H5活动页面,产品要求初始化播放音乐,因晓得H5 Audio标签支持Autoplay就没在意. 完了在手机上测试,发现手机上打开页面死活就是不会自动播放,点击播放按钮才可以播放,很是纠结 ...

  5. javascript移动设备Web开发中对touch事件的封装实例

    在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 ta ...

  6. Introduction to Microsoft Dynamics 365 licensing

    Microsoft Dynamics 365 will be released on November 1. In preparation for that, Scott Guthrie hosted ...

  7. IT软件人员的技术学习内容(写给技术迷茫中的你) - 项目管理系列文章

    前面笔者曾经写过一篇关于IT从业者的职业道路文章(见笔者文:IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章).然后有读者提建议说写写技术方面的路线,所以就有了本文.本文从初学者到思想 ...

  8. <<你的灯亮着吗?>>读书笔记

    本书是美国计算机传奇人物杰拉尔德.温伯格和唐纳德.高斯所著,我在网上买到的2003年版的本书,发现本书用20则幽默的现代寓言故事,60幅精美插图,以及一系列的适当提问和建议,让我们的思考方式慢慢得以扩 ...

  9. SQLServer中的页如何影响数据库性能 (转)

    无论是哪一个数据库,如果要对数据库的性能进行优化,那么必须要了解数据库内部的存储结构.否则的话,很多数据库的优化工作无法展开.对于对于数据库管理员来说,虽然学习数据库的内存存储结构比较单调,但是却是我 ...

  10. EntityFramework简介

    EntityFramework是什么? 1.是对ADO.NET 更高封装的ORM (对象关系映射)框架,跟Nhibernate类似 2.用面向对象的方式来操作关系数据库 3.目标: 提高开发效率,减轻 ...