absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] [-51] UVaLive 6778 - Sensor Network
[破碎的状态] [-37] 100818 B-分块解法

[破碎的状态] [-38] 100818 B

absi2011 posted @ Jun 14, 2016 03:53:28 PM in 刷题记录 with tags 树状数组 小高考 CF Gym 树链剖分 , 462 阅读

这一题题意:

给你n个点的一颗树(n<=500000)

一共有q次询问,每次询问要你完成k次修改以后,进行一个查询(q<=50000 k<=1000)

问[u,v]以及它们的路径上的所有的点的权值和

k次修改是读入后随机生成的,具体来说是这样的

输入[tex]x_1,y_1,A,B,C,D[/tex]

对于x>=2,我们有

[tex]x_i = (x_{i-1} * A + B)\ mod\ N[/tex]

[tex]y_i = (y_{i-1} * C + D)\ mod\ 10^9+7[/tex]

然后把第[tex]x_i[/tex]个点的权值加上[tex]y_i[tex]

时限8s

直接树链剖分剖分一下

用树状数组代替线段树来维护这个树链剖分

复杂度是[tex]O(k*q \log n+n \log^2 n)[/tex]

看起来还是挺可做的..就这么..过了..

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<string>
#include<time.h>
#include<bitset>
#include<vector>
#include<memory>
#include<utility>
#include<stdio.h>
#include<sstream>
#include<fstream>
#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[500005];
int n;
long long c[500005];
inline void change(int x,int val)
{
    x++;
    for (;;)
    {
        c[x]+=val;
        x+=(-x)&x;
        if (x>n) return;
    }
}
inline long long queries(int x)
{
    long long sum=0;
    for (;;)
    {
        if (x==0) return sum;
        sum+=c[x];
        x^=(-x)&x;
    }
}
inline long long query(int l,int r)
{
    return queries(r+1)-queries(l);
}
struct edge
{
    int y;
    edge * next;
};
edge * li[500005];
edge * new_edge()
{
    static edge a[1000005];
    static int top=0;
    return &a[top++];
}
void inserts(int x,int y)
{
    edge * t=new_edge();
    t->y=y;
    t->next=li[x];
    li[x]=t;
}
void insert_edge(int x,int y)
{
    inserts(x,y);
    inserts(y,x);
}
int father[500005];
int dfn[500005];
int depth[500005];
int vis[500005];
int size[500005];
edge * prefer_child[500005];
int up[500005];
void dfs1(int x)
{
    edge * t;
    size[x]=1;
    prefer_child[x]=0;
    int max_size=0;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==father[x]) continue;
        father[t->y]=x;
        depth[t->y]=depth[x]+1;
        dfs1(t->y);
        size[x]+=size[t->y];
        if (size[t->y]>max_size)
        {
            max_size=size[t->y];
            prefer_child[x]=t;
        }
    }
}
void dfs2(int x)
{
    static int num=0;
    dfn[x]=num;
    vis[num]=x;
    num++;
    if (prefer_child[x]==0) return;
    up[prefer_child[x]->y]=up[x];
    dfs2(prefer_child[x]->y);
    edge * t;
    for (t=li[x];t!=0;t=t->next)
    {
        if (t->y==father[x]) continue;
        if (t==prefer_child[x]) continue;
        up[t->y]=t->y;
        dfs2(t->y);
    }
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    ios::sync_with_stdio(false);
    scanf("%d",&n);
    int i;
    for (i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        insert_edge(x,y);
    }
    father[0]=-1;
    depth[0]=0;
    dfs1(0);
    up[0]=0;
    dfs2(0);
    for (i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    for (i=1;i<=n;i++)
    {
        c[i]+=a[vis[i-1]];
        int j=i;
        j=j+(j&(-j));
        if (j>n) continue;
        c[j]+=c[i];
    }
    int m;
    scanf("%d",&m);
    for (i=0;i<m;i++)
    {
        int k,x1,y1,aa,bb,cc,dd,x,y;
        scanf("%d%d%d%d%d%d%d%d%d",&k,&x1,&y1,&aa,&bb,&cc,&dd,&x,&y);
        int j;
        if (x1<n) change(dfn[x1],y1);
        for (j=1;j<k;j++)
        {
            x1=((long long)x1*aa+bb)%n;
            y1=((long long)y1*cc+dd)%1000000007;
            change(dfn[x1],y1);
        }
        long long sum=0;
        for (;;)
        {
            if (up[x]==up[y])
            {
                if (depth[x]<depth[y]) swap(x,y);
                sum+=query(dfn[y],dfn[x]);
                break;
            }
            else
            {
                if (depth[up[x]]<depth[up[y]]) swap(x,y);
                sum+=query(dfn[up[x]],dfn[x]);
                x=father[up[x]];
            }
        }
        cout<<sum<<'\n';
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter