Codeforces Round #524 (Div. 2) F

题解:

首先这个东西因为强制在线区间查询

所以外面得套线段树了

然后考虑几条线段怎么判定

我们只需要按照右端点排序,然后查询的时候查找最右节点的前缀最大值就可以了

然后怎么合并子区间信息呢

(刚开始我很zz的觉得应该要线段树合并。。)

线段树都保证了区间一样大每个点暴力也就会算log次。。

于是就直接暴力合并就好了

复杂度$nlog^2$

然后因为是cf题。。完全不管常数 成功跑了luogu倒数rank1

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define mep(x,y) memcpy(x,y,sizeof(y))
#define mid ((h+t)>>1)
namespace IO{
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T> void read(T &x)
    {
        rint f=1,c; while (c=gc(),c<48||c>57) if (c==‘-‘) f=-1; x=(c^48);
        while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    char sr[1<<24],z[20]; int Z,C1=-1;
    template<class T>void wer(T x)
    {
        if (x<0) sr[++C1]=‘-‘,x=-x;
        while (z[++Z]=x%10+48,x/=10);
        while (sr[++C1]=z[Z],--Z);
    }
    IL void wer1()
    {
        sr[++C1]=‘ ‘;
    }
    IL void wer2()
    {
        sr[++C1]=‘\n‘;
    }
    template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
    template<class T>IL void mina(T &x,T y) {if (x>y) x=y;}
    template<class T>IL T MAX(T x,T y){return x>y?x:y;}
    template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
using namespace IO;
const int N=3.1e5;
const int N1=N*4;
struct re{
    int a,b;
};
bool cmp(re x,re y)
{
    return x.b<y.b;
}
vector<re> ve[N];
struct sgt{
    vector<re> ve1[N1];
    IL void updata(int x)
    {
        int l1=(int)(ve1[x*2].size())-1;
        int l2=(int)(ve1[x*2+1].size())-1;
        int h1=0,h2=0,lst1=0,lst2=0;
        while (h1<=l1||h2<=l2)
        {
            int t;
            if (h1<=l1&&h2<=l2)
              t=MIN(ve1[x*2][h1].b,ve1[x*2+1][h2].b);
            else if (h1<=l1) t=ve1[x*2][h1].b; else t=ve1[x*2+1][h2].b;
            while (h1<=l1&&ve1[x*2][h1].b==t)
              maxa(lst1,ve1[x*2][h1].a),h1++;
            while (h2<=l2&&ve1[x*2+1][h2].b==t)
              maxa(lst2,ve1[x*2+1][h2].a),h2++;
            ve1[x].push_back((re){MIN(lst1,lst2),t});
        }
    }
    void build(int x,int h,int t)
    {
        if (h==t)
        {
          int l=(int)(ve[h].size())-1;
          rep(i,0,l) ve1[x].push_back(ve[h][i]);
          sort(ve1[x].begin(),ve1[x].end(),cmp);
          int lst=0;
          rep(i,0,l)
          {
              maxa(lst,ve1[x][i].a);
            ve1[x][i].a=lst;
          }
          return;
        }
        build(x*2,h,mid); build(x*2+1,mid+1,t);
        updata(x);
    }
    IL bool query(int x,int h,int t,int h1,int t1,int x1,int y)
    {
        if (h1<=h&&t<=t1)
        {
          int h=0,t=(int)(ve1[x].size())-1;
          if (t<0) return(0);
          if (ve1[x][h].b>y) return(0);
          while (h<t)
          {
              int mid2=(h+t+1)/2;
              if (ve1[x][mid2].b<=y) h=mid2; else t=mid2-1;
          }
          if (ve1[x][h].a>=x1) return(1); else return(0);
        }
        bool tt=1;
        if (h1<=mid) tt&=query(x*2,h,mid,h1,t1,x1,y);
        if (mid<t1) tt&=query(x*2+1,mid+1,t,h1,t1,x1,y);
        return tt;
    }
}S;
int main()
{
    int n,m,k;
    ios::sync_with_stdio(false);
    cin>>n>>m>>k;
    rep(i,1,k)
    {
        int x,y,z;
        cin>>x>>y>>z;
        ve[z].push_back((re){x,y});
    }
    S.build(1,1,n);
    rep(i,1,m)
    {
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        if (S.query(1,1,n,x1,y1,x2,y2)) cout.flush()<<"yes"<<endl;
        else cout.flush()<<"no"<<endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/yinwuxiao/p/10103967.html

时间: 2024-10-08 06:37:47

Codeforces Round #524 (Div. 2) F的相关文章

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/contest/988/problem/E Description Polycarp lives on a coordinate line at the point x=0. He goes to his friend that lives at the point x=a. Polycarp can

Codeforces Round #501 (Div. 3) F. Bracket Substring

题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60949 ....看不懂 设dp[i][j][l]表示前i位,左括号-右括号=j,匹配到l了 状态转移,枚举下一个要填的括号,用next数组求状态的l,分别转移 代码 #include<bits/stdc++.h> using namespace std; const int maxn = 207;

Codeforces Round #392 (Div. 2) F. Geometrical Progression

原题地址:http://codeforces.com/contest/758/problem/F F. Geometrical Progression time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output For given n, l and r find the number of distinct geometrical pro

Codeforces Round #531 (Div. 3) F. Elongated Matrix(状压DP)

F. Elongated Matrix 题目链接:https://codeforces.com/contest/1102/problem/F 题意: 给出一个n*m的矩阵,现在可以随意交换任意的两行,最后从上到下,从左到右形成一个序列s1,s2.....snm,满足对于任意相邻的两个数,它们差的绝对值的最大值为k. 现在问怎么交换行与行,可以使得最后的这个k最大. 题解: 人生中第一道状压dp~其实还是参考了这篇博客:https://blog.csdn.net/CSDNjiangshan/art

Codeforces Round #548 (Div. 2) F splay(新坑) + 思维

https://codeforces.com/contest/1139/problem/F 题意 有m个人,n道菜,每道菜有\(p_i\),\(s_i\),\(b_i\),每个人有\(inc_j\),\(pref_j\),一个人可以买一道菜的条件是 1. \(p_i \leq inc_j \leq s_i\) 2. \(|b_i - pref_j| \leq inc_j-p_i\) ,问每个人分别能买多少道菜 题解 转化一下公式 \(p_i \leq inc_j \leq s_i\) 下面两个满

Codeforces Round #549 (Div. 2) F 数形结合 + 凸包(新坑)

https://codeforces.com/contest/1143/problem/F 题意 有n条形如\(y=x^2+bx+c\)的抛物线,问有多少条抛物线上方没有其他抛物线的交点 题解 \(y=x^2+bx+c=>y+x^2=bx+c\),转换为点\((x,y+x^2)\)在bx+c的直线上 两个点确定一条抛物线,同时也确定了一条直线 需要选择最上面那些点相邻确定的抛物线,所以维护一个上凸包即可 维护上凸包,当前点在前进方向左边需要向后退,cross(a,b)>=0 代码 #inclu

Codeforces Round #524 (Div. 2) codeforces 1080A~1080F

目录 codeforces1080A codeforces 1080B codeforces 1080C codeforces 1080D codeforces 1080E codeforces 1080F codeforces1080A 传送门:https://codeforces.com/contest/1080/problem/A 题意:制造一份邀请函需要2份a物品,5份b物品,8份c物品,一个盒子里面有k份物品(可以为a或b或c)问你制造n份邀请函需要用多少个盒子 题解:直接加起来就行

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

题:https://codeforces.com/contest/1099/problem/F 题意:给定一个树,每个节点有俩个信息x和t,分别表示这个节点上的饼干个数和先手吃掉这个节点上一个饼干的的时间.然后有先手和后手俩个人. ?先手可以这么操作:在规定总时间T到达某个节点然后一定要返回根节点1,期间可以选择吃掉某些节点上的某些饼干(前提是保证剩下的时间能够回到根节点): ?后手可以这么操作:在先手到达的位置和这个位置的孩子之间的连边选择一条让先手吃得更多的边摧毁掉,也可以跳过这个过程: 问

Codeforces Round #615 (Div. 3) F. Three Paths on a Tree

F. Three Paths on a Tree 原题链接:https://codeforces.com/contest/1294/problem/F 题目大意: 给定一棵树,选出三点,使三点连成的j简单路径最大.简而言之,三个点连成的边的集合大小. 解题思路: 假设任取一点为三点连线的公共点,最长路径就是这个点到其他三个点的三条最长边之和,可知这个点一定在直径上(画图分析假设不在时的最长路径可反证).所以先求出树的直径,在使用$ans =(a b+a c+b c) / 2$遍历可以得到第三个点