Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)

题目:http://codeforces.com/problemset/problem/356/A

题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所击败了(l<=x<=r),被击败的人立马退出游戏让你最后输出每个人是被谁击败的,最后那个胜利者没被

人击败就输出0

思路:他的每次修改的是一个区间的被击败的人,他而且只会记录第一次那个被击败的人,用线段树堕落标记的话他会记录最后一次的,所以我们倒着来修改,

然后因为那个区间里面还包含了自己,在线段树操作里面修改不太方便,所以我们采用把他拆分成两个区间来操作

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
struct tree
{
    int l,r;
    int val;
}d[300005*4];
struct sss
{
    int x,y,z;
}a[300005];
int n,m;
void buildtree(int cnt,int l,int r)
{
    if(cnt>n*4) return;
    d[cnt].l=l;
    d[cnt].r=r;
    int mid=(l+r)/2;
    buildtree(cnt*2,l,mid);
    buildtree(cnt*2+1,mid+1,r);
}
void pushdown(int cnt)
{
    if(d[cnt].val!=0){
        d[cnt*2].val=d[cnt].val;
        d[cnt*2+1].val=d[cnt].val;
        d[cnt].val=0;
    }
}
void update(int cnt,int l,int r,int val){
    if(l==d[cnt].l&&r==d[cnt].r){
        d[cnt].val=val;
        return;
    }
    pushdown(cnt);
    int mid=(d[cnt].l+d[cnt].r)/2;
    if(r<=mid) update(cnt*2,l,r,val);
    else if(l>mid) update(cnt*2+1,l,r,val);
    else{
        update(cnt*2,l,mid,val);
        update(cnt*2+1,mid+1,r,val);
    } 

}
void query(int cnt,int x)
{
    if(d[cnt].l==d[cnt].r){
        if(d[cnt].val==x) printf("0 ");
        else printf("%d ",d[cnt].val);
        return;
    }
    pushdown(cnt);
    int mid=(d[cnt].l+d[cnt].r)/2;
    if(x<=mid) query(cnt*2,x);
    else  query(cnt*2+1,x);

}
int main()
{
    cin>>n>>m;
    for(int i=0;i<m;i++){
        cin>>a[i].x>>a[i].y>>a[i].z;
    }
    buildtree(1,1,n);
    for(int i=m-1;i>=0;i--){
        if(a[i].z-1>=a[i].x) //拆分成两个区间来修改
            update(1,a[i].x,a[i].z-1,a[i].z);
        if(a[i].z+1<=a[i].y)
            update(1,a[i].z+1,a[i].y,a[i].z);
    }
    for(int i=1;i<=n;i++){
        query(1,i);
    }
} 

原文地址:https://www.cnblogs.com/Lis-/p/10690019.html

时间: 2024-09-30 20:01:02

Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)的相关文章

Codeforces Round #426 (Div. 2) D. The Bakery(线段树维护dp)

题目链接: Codeforces Round #426 (Div. 2) D. The Bakery 题意: 给你n个数,划分为k段,每段的价值为这一段不同的数的个数,问如何划分,使得价值最大. 题解: 考虑dp[i][j]表示划分为前j个数划分为i段的最大价值,那么这就是一个n*n*k的dp, 考虑转移方程dp[i][j]=max{dp[i][k]+val[k+1][j]},我们用线段树去维护这个max,线段树上每个节点维护的值是dp[i][k]+val[k+1][j],对于每加进来的一个数a

Codeforces Round #424 (Div. 2) E. Cards Sorting(线段树)

题目链接:Codeforces Round #424 (Div. 2) E. Cards Sorting 题意: 将n个数放进一个队列,每次检查队首,看看是不是队列中最小的数,如果是就扔掉,如果不是就放到队尾. 这样直到队列为空,为需要操作多少次. 题解: 考虑用两个指针模拟,最开始now指针指向第一个数,然后nxt指针指向下一个将要被删除的数. 然后我们要算出这里需要移动多少步,然后删掉这个数,一直重复操作,直到将全部的数删完. nxt指针可以用set来维护,now指针可以用并查集来维护. 计

Codeforces Round #603 (Div. 2) E. Editor(线段树)

链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard problem. You need to implement an extra module for brackets coloring in text. Your editor consists of a line with infinite length and cursor, which point

Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/427/B Description The prison of your city has n prisoners. As the prison can't accommodate all of them, the city mayor has decided to transfer c

Codeforces Round #271 (Div. 2) F.Ant colony(线段树 + 统计区间内某数的个数)

F. Ant colony Mole is hungry again. He found one ant colony, consisting of n ants, ordered in a row. Each ant i (1 ≤ i ≤ n) has a strength si. In order to make his dinner more interesting, Mole organizes a version of «Hunger Games» for the ants. He c

Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并

D. Developing Game Pavel is going to make a game of his dream. However, he knows that he can't make it on his own so he founded a development company and hired n workers of staff. Now he wants to pick n workers from the staff who will be directly res

Codeforces Round #275 Div.1 B Interesting Array --线段树

题意: 构造一个序列,满足m个形如:[l,r,c] 的条件. [l,r,c]表示[l,r]中的元素按位与(&)的和为c. 解法: 线段树维护,sum[rt]表示要满足到现在为止的条件时该子树的按位与和至少为多少. 更新时,如果val的pos位为1,那么整个区间的按位与和pos位也应该为1,否则与出来就不对了.(这是本题解题的核心) 那么此时更新 sum[rt] |= val 即可.然后再check一遍看是否满足所有条件即可. 代码: #include <iostream> #inclu

Codeforces Round #530 (Div. 2) E (树形dp+线段树)

链接: 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干需要花费bi时间,有两个玩家,玩家一可以移动到当前点的子节点也可以申请游戏结束返回根节点并吃沿途的饼干,玩家二可以删除当前点到儿子节点的一条边,走路和吃饼干都消耗时间,会给出一个总时间,在总时间内尽可能的多吃饼干,问最多能吃多少个? 思路: 由于是玩家一先手,那么最开始的最大边则不会被删除,但之后路途的最大边都会被玩家二删除,所以我们对于当前点我们需要求: 1.如果现在回头那么最多可以吃到多少饼干 2.向下

Codeforces Round #587 (Div. 3) F Wi-Fi(线段树+dp)

题意:给定一个字符串s 现在让你用最小的花费 覆盖所有区间 思路:dp[i]表示前i个全覆盖以后的花费 如果是0 我们只能直接加上当前位置的权值 否则 我们可以区间询问一下最小值 然后更新 #include <bits/stdc++.h> using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-6; const int N = 2e5+7; typedef long long ll; const ll mod