您的位置:首页 > 运维架构

2015多校第九,十场总结

2015-10-30 20:50 387 查看
1010 sometiems naive

树链剖分。从根到任意节点的路径不超过log2n条轻链,因此,轻链可以单独维护。

#define clr(A,x) memset(A,x,sizeof(A))

using namespace std;
typedef long long LL;
typedef pair<int,int> P;
typedef pair<int,P> pp;
typedef complex<double> cpx;
const int mm = 1e5+5;
const int mod = 1000000007;

using namespace std;
int n, m;
int w[mm];

vector<int> g[mm];
LL sum = 0;
void input()
{
for(int i = 1; i <= n; i++)
{
scanf("%d",w+i);
}
for(int i = 0; i <= n; i++) g[i].clear();
for(int i = 1; i < n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
}

int fa[mm],sz[mm],hson[mm],top[mm];
int id[mm],idx,d[mm],di[mm];

void dfs_sz(int rt)
{
//    sumw[rt] = w[rt];
sz[rt] = 1;d[rt] = d[fa[rt]]+1;
int &son = hson[rt];
for(int i = 0; i < g[rt].size(); i++)
if(g[rt][i] != fa[rt]){
int &u = g[rt][i];
fa[u] = rt;
dfs_sz(u);
sz[rt] += sz[u];
//        sumw[rt] += sumw[u];
if(son == 0 || sz[son] < sz[u]) son = u;
}
}

void dfs_chain(int rt,int anc)
{
id[rt] = ++idx;di[idx] = rt;
top[rt] = anc;
int &son = hson[rt];
if(son != 0) dfs_chain(son,anc);
for(int i = 0; i < g[rt].size(); i++)
{
int &u = g[rt][i];
if(u == son || u == fa[rt]) continue;
dfs_chain(u,u);
}
}

int N;

void modify(LL C[],int x,int dx)
{
for(x; x < N; x += x&(-x))
{
C[x] = (C[x] + dx) % mod;
//        if(C[x] >= mod) C[x] -= mod;
}
}

LL getsum(LL C[],int x)
{
LL res = 0;
for(x;x > 0; x -= x&(-x))
{
res = (res + C[x]) % mod;
//        if(res >= mod) res -= mod;
}
return res;
}

const int root = 1;

LL C2[mm],C0[mm];

//LL A1[mm],A0[mm];

void change(int u,int uw)
{
//    int v = root;
//    LL dx2 = (LL)uw*uw - (LL)w[u]*w[u];
LL dx1 = uw - w[u];
sum = (sum + dx1) % mod;

//    if(sum >= mod) sum -= mod;
w[u] = uw;
while(top[u] != root)
{
LL x = getsum(C0,id[top[u]]);
LL dx2 = (x+dx1)*(x+dx1) % mod - x*x % mod;
dx2 %= mod;
modify(C2,id[fa[top[u]]],dx2);
modify(C0,id[top[u]],dx1);
modify(C0,id[u]+1,-dx1);
u = fa[top[u]];
}
modify(C0,id[root],dx1);
modify(C0,id[u]+1,-dx1);
}

LL query(int u,int v)
{
LL res = 0;
while(top[u] != top[v])
{
if(d[top[u]] < d[top[v]]) swap(u,v);
res += getsum(C2,id[u]) - getsum(C2,id[top[u]]-1);
res %= mod;
int &son = hson[u];
if(son != 0){
LL x = getsum(C0,id[son]);
res += x*x % mod;
}
LL x = getsum(C0,id[top[u]]);
res -= x*x % mod;
res %= mod;
u = fa[top[u]];
}

if(d[u] < d[v]) swap(u,v);

res += getsum(C2,id[u]) - getsum(C2,id[v]-1);
int &son = hson[u];
if(son != 0){
LL x = getsum(C0,id[son]);
res += x*x % mod;
}
LL x = sum - getsum(C0,id[v]);
res += x*x % mod;
return (res % mod + mod ) % mod;
}

void solve()
{
clr(hson,0);
idx = 0;d[root] = 0;
fa[root] = root;
dfs_sz(root);
dfs_chain(root,root);
//    for(int i = 1; i <= n; i++)
//    {
//        printf("%d %d %d %d\n",fa[i],id[i],hson[i],top[i]);
//    }
//    cout << "-------" << endl;
N = n + 3;
clr(C0,0);clr(C2,0);
sum = 0;
for(int i = 1; i <= n; i++)
{
int x = w[i];
w[i] = 0;
change(i,x);
}

//    for(int i = 1; i <= n; i++)
//    {
//        cout <<getsum(C0,id[i]) << " " ;
//    }
//    cout << endl << "----->" <<endl;
for(int i = 0; i < m; i++)
{
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
if(op == 1){
change(u,v);
}else{
LL ans = (sum*sum % mod - query(u,v)) % mod;
printf("%I64d\n",(ans + mod) % mod);
}
}
}

int main()
{
//    freopen("wcbao.in","r",stdin);
//    int T;
while(cin >> n >> m)
{
input();
solve();
}
return 0;
}


2. 十 1001 CRB and Apple

数据结构优化dp转移令i < j,

dp[j][i]=dp[i][j]=1+max{dp[i][k]|k<j,d[k]<=d[j]}

3 . 十 1004 CRB and Graph

If multiple critical pairs exist, output the pair with largest u. If still ambiguous, output the pair with smallest v.

其中,u < v。

题解分析的好。将[1,n]分为两个集合A,B。A中最大值为N,B中最大值为B,则答案为(B,B+1)。


4 . 十 1008 CRB and Roads

DAG任意两点的可达性判断。乱搞。O(N*M)复杂度,用01表示可达性,用bitset或者int压缩一下简化复杂度。O(N∗M/32)。就是说不一定老用乘法,复杂度可以做除法(优化)。

5 . 十 1010 CRB and Substrings

对s每次头部去一个,尾部加一个,动态维护后缀数组?

没见过。

6 . 十 1011 CRB and Tree

给一棵节点带权的树,f(u,v)表示路径u到v的所有节点权值异或和。询问f(u,v)=s的对数。f(u,v)=f(u,root)⊗f(root,v)异或和的优美性质
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息