【Codeforces696E】...Wait for it...

本文介绍了一种使用树剖结合线段树的数据结构来高效处理动态区间查询及更新问题的方法。通过预处理和递归分解技术,该方法能够在对数时间内完成单点删除操作,并保持线段树上维护的信息更新。适用于解决复杂图论问题中涉及的大量查询与修改需求。

一个一个删,树剖线段树上维护即可。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define mid (l+r>>1)
#define inf (ll)2e18
#define N 100009
#define root 1,1,n
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
#define now cur,l,r
using namespace std;
ll n,m,Q,first[N],number,fa[N],size[N],top[N],deep[N],Mson[N],dfn[N],id[N],ed[N],cnt;
ll tg[N<<2],print[N],pos[N];
struct edge
{
    ll to,next;
    void add(ll x,ll y)
    {
        to=y,next=first[x],first[x]=number;
    }
}e[N<<1];
struct node
{
    ll pos,val,id;
    node(ll pos=0,ll val=0,ll id=0):pos(pos),val(val),id(id){}
    bool operator <(const node &rhs) const
    {
        return val<rhs.val||(val==rhs.val&&pos<rhs.pos);
    }
}Min[N<<2];
vector<node> a[N];
ll read()
{
    ll x=1;
    char ch;
    while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
    ll s=ch-'0';
    while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
    return s*x;
}
void dfs1(ll x)
{
    deep[x]=deep[fa[x]]+1;
    size[x]=1;
    for (ll i=first[x];i;i=e[i].next)
        if (e[i].to!=fa[x])
        {
            fa[e[i].to]=x;
            dfs1(e[i].to);
            size[x]+=size[e[i].to];
            if (size[e[i].to]>size[Mson[x]]) Mson[x]=e[i].to;
        }
}
void dfs2(ll x,ll y)
{
    top[x]=y;
    id[dfn[x]=++cnt]=x;
    if (Mson[x]) dfs2(Mson[x],y);
    for (ll i=first[x];i;i=e[i].next)
        if (e[i].to!=fa[x]&&e[i].to!=Mson[x]) dfs2(e[i].to,e[i].to);
    ed[x]=cnt;
}
void down(ll cur,ll l,ll r)
{
    if (tg[cur]>0)
    {
        tg[lc]+=tg[cur];
        tg[rc]+=tg[cur];
        Min[lc].val+=tg[cur];
        Min[rc].val+=tg[cur];
        tg[cur]=0;
    }
}
void up(ll cur,ll l,ll r)
{
    Min[cur]=min(Min[lc],Min[rc]);
}
void build(ll cur,ll l,ll r)
{
    tg[cur]=0;
    if (l==r)
    {
        Min[cur]=(a[id[l]].size()!=0?a[id[l]][0]:node(0,inf,inf));
        return;
    }
    build(lson);
    build(rson);
    up(now);
}
void ins(ll cur,ll l,ll r,ll L,ll R,ll x)
{
    if (L<=l&&R>=r)
    {
        tg[cur]+=x;
        Min[cur].val+=x;
        return;
    }
    down(now);
    if (L<=mid) ins(lson,L,R,x);
    if (R>mid) ins(rson,L,R,x);
    up(now);
}
ll get_tg(ll cur,ll l,ll r,ll x)
{
    if (l==r) return tg[cur];
    if (x<=mid) return tg[cur]+get_tg(lson,x);
    else return tg[cur]+get_tg(rson,x);
}
void del(ll cur,ll l,ll r,ll x)
{
    if (l==r)
    {
        pos[id[l]]++;
        Min[cur]=(a[id[l]].size()>pos[id[l]]?a[id[l]][pos[id[l]]]:node(0,inf,inf));
        if (a[id[l]].size()>pos[id[l]]) Min[cur].val+=get_tg(root,l);
        return;
    }
    down(now);
    if (x<=mid) del(lson,x);
    else del(rson,x);
    up(now);
}
node qry(ll cur,ll l,ll r,ll L,ll R)
{
    if (L<=l&&R>=r) return Min[cur];
    down(now);
    node ret=node(0,inf,inf);
    if (L<=mid) ret=min(ret,qry(lson,L,R));
    if (R>mid) ret=min(ret,qry(rson,L,R));
    return ret;
}
node qry(ll x,ll y)
{
    node ret=node(0,inf,inf);
    for (;top[x]!=top[y];x=fa[top[x]])
    {
        if (deep[top[x]]<deep[top[y]]) swap(x,y);
        ret=min(ret,qry(root,dfn[top[x]],dfn[x]));
    }
    if (dfn[x]>dfn[y]) swap(x,y);
    return min(ret,qry(root,dfn[x],dfn[y]));
}
int main()
{
    n=read(),m=read(),Q=read();
    //n=1,m=100000,Q=100000;
    for (ll i=1;i<n;i++)
    {
        ll x=read(),y=read();
        e[++number].add(x,y),e[++number].add(y,x);
    }
    for (ll i=1;i<=m;i++)
    {
        ll x=read();
        //ll x=1;
        a[x].push_back(node(x,i,i));
    }
    for (ll i=1;i<=n;i++) pos[i]=0,sort(a[i].begin(),a[i].end());
    dfs1(1);
    dfs2(1,1);
    build(root);
    while (Q--)
    {
        ll op=read();
        //ll op=1;
        if (op==1)
        {
            ll x=read(),y=read(),k=read(),num=0;
            //ll x=1,y=1,k=1,num=0;
            for (num=0;num<k;num++)
            {
                node Now=qry(x,y);
                if (Now.pos==0) break;
                else
                {
                    print[num+1]=Now.id;
                    del(root,dfn[Now.pos]);
                }
            }
            printf("%lld",num);
            for (ll i=1;i<=num;i++) printf(" %lld",print[i]);
            puts("");
        }
        else
        {
            ll x=read(),k=read();
            ins(root,dfn[x],ed[x],k);
        }
    }
    return 0;
}
F. Attraction Theory time limit per test2 seconds memory limit per test256 megabytes Taylor Swift - Love Story (Taylor's Version) ⠀ There are 𝑛 people in positions 𝑝1,𝑝2,…,𝑝𝑛 on a one-dimensional coordinate axis. Initially, 𝑝𝑖=𝑖 for each 1≤𝑖≤𝑛. You can introduce an attraction at some integer coordinate 𝑥 (1≤𝑥≤𝑛), and then all the people will move closer to the attraction to look at it. Formally, if you put an attraction in position 𝑥 (1≤𝑥≤𝑛), the following changes happen for each person 𝑖 (1≤𝑖≤𝑛): if 𝑝𝑖=𝑥, no change; if 𝑝𝑖<𝑥, the person moves in the positive direction, and 𝑝𝑖 is incremented by 1; if 𝑝𝑖>𝑥, the person moves in the negative direction, and 𝑝𝑖 is decremented by 1. You can put attractions any finite number of times, and in any order you want. It can be proven that all positions of a person always stays within the range [1,𝑛], i.e. 1≤𝑝𝑖≤𝑛 at all times. Each position 𝑥 (1≤𝑥≤𝑛), has a value 𝑎𝑥 associated with it. The score of a position array [𝑝1,𝑝2,…,𝑝𝑛], denoted by 𝑠𝑐𝑜𝑟𝑒(𝑝), is ∑𝑛𝑖=1𝑎𝑝𝑖, i.e. your score increases by 𝑎𝑥 for every person standing at 𝑥 in the end. Over all possible distinct position arrays 𝑝 that are possible with placing attractions, find the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝). Since the answer may be large, print it modulo 998244353. Input Each test contains multiple test cases. The first line contains the number of test cases 𝑡 (1≤𝑡≤104). The description of the test cases follows. The first line of each test case contains a single integer 𝑛 (1≤𝑛≤2⋅105). The second line of each test case contains 𝑛 integers — 𝑎1,𝑎2,…,𝑎𝑛 (1≤𝑎𝑖≤109) It is guaranteed that the sum of 𝑛 over all test cases does not exceed 2⋅105. Output For each test case, output a single line containing an integer: the sum of 𝑠𝑐𝑜𝑟𝑒(𝑝) over all possible distinct position arrays 𝑝 that are possible with placing attractions, modulo 998244353. Example inputCopy 7 1 1 2 5 10 3 1 1 1 4 1 1 1 1 4 10 2 9 7 5 1000000000 1000000000 1000000000 1000000000 1000000000 8 100 2 34 59 34 27 5 6 outputCopy 1 45 24 72 480 333572930 69365 Note In the first test case, the only possible result is that person 1 stays at 1. The score of that is 𝑎1=1. In the second test case, the following position arrays [𝑝1,𝑝2] are possible: [1,2], score 15; [1,1], score 10; [2,2], score 20. The sum of scores is 15+10+20=45. In the third test case, the following position arrays [𝑝1,𝑝2,𝑝3] are possible: [1,1,1]; [1,1,2]; [1,2,2]; [1,2,3]; [2,2,2]; [2,2,3]; [2,3,3]; [3,3,3]. Each has a score of 3, and thus the total sum is 24.解决这道题,用c++
最新发布
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值