首页 > 其他分享 >uoj839 龙门题字 题解

uoj839 龙门题字 题解

时间:2024-02-09 14:57:18浏览次数:42  
标签:cnt ch 修改 read 题解 uoj839 id int 题字

题目链接

点击打开链接

题目解法

呜呜呜,我考场上只会 \(60\),不会优化,没救了

要求字典序最大,不难想到一位一位钦定,那么我们现在的问题是判断 \(ans_1,...,ans_i\) 是否合法,记 \(ok_{i,j}\) 表示第 \(i\) 个修改在第 \(j\) 位是否可行(即 \(x_{i,j}\ge ans_j\)),同时记 \(cnt_i\) 为第 \(i\) 个修改有多少位不可行
考虑修改的过程倒过来,那么可以作为最后一个修改的条件是 \(cnt_{x}=0\),同理我们往前推,把最后一次修改的位置全部刨去,然后继续找 \(cnt=0\) 的位置(注意是不包含刨去的位置)
这样精细维护可以做到 \(O(nL)\)
具体如何维护?用队列存当前为 \(cnt=0\) 的修改,每次取出队头,把没有刨去的位置刨去,然后看哪些修改的 \(cnt\) 会变成 \(0\),把 \(cnt\) 变成 \(0\) 的再加入队列,就可以做到 \(O(L)\) 判断

从这个入手,我们发现每次后面只添加了一个元素 \(i\),前 \([1,...,i-1]\) 是没有变化的
考虑先把 \(r\le i\) 的修改能做的都做完,那么现在必须做包含 \(i\) 的修改了,那么就找一个第 \(i\) 位最大的能选的修改即可
我们需要动态加入 \(r=i\) 的修改,这个可以用前文的队列维护,因为它可能连环导致之前 \(r'<i\) 的修改可行

时间复杂度 \(O(n+L)\)

#include <bits/stdc++.h>
#define F(i,x,y) for(int i=(x);i<=(y);i++)
#define DF(i,x,y) for(int i=(x);i>=(y);i--)
#define ms(x,y) memset(x,y,sizeof(x))
#define SZ(x) (int)x.size()-1
#define all(x) x.begin(),x.end()
#define pb emplace_back
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int,int> pii;
template<typename T> void chkmax(T &x,T y){ x=max(x,y);}
template<typename T> void chkmin(T &x,T y){ x=min(x,y);}
inline int read(){
    int FF=0,RR=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
    for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
    return FF*RR;
}
const int N=200010;
int n,m,L[N],R[N],deg[N],ans[N];
bool ok[N],tag[N];
vector<int> b[N],vec1[N],vec2[N];
queue<int> Q;
int main(){
    n=read(),m=read();
    L[0]=1,R[0]=n;
    F(i,1,n) b[0].pb(read()),vec1[i].pb(0);
    F(i,1,m){
        L[i]=read(),R[i]=read();
        F(j,L[i],R[i]) b[i].pb(read()),vec1[j].pb(i);
        vec2[R[i]].pb(i);
    }
    F(i,1,n){
        for(int id:vec1[i]) if(!deg[id]) chkmax(ans[i],b[id][i-L[id]]);
        for(int id:vec1[i]) deg[id]+=(b[id][i-L[id]]<ans[i]);
        for(int id:vec2[i]) if(!deg[id]) Q.push(id);
        while(!Q.empty()){
            int id=Q.front();Q.pop();
            tag[id]=true;
            F(j,L[id],R[id]) if(!ok[j]){
                ok[j]=true;
                for(int to:vec1[j]) if(b[to][j-L[to]]<ans[j]){
                    deg[to]--;
                    if(R[to]<=i&&!deg[to]) Q.push(to);
                }
            }
        }
    }
    F(i,1,n) printf("%d ",ans[i]);puts("");
    return 0;
}

标签:cnt,ch,修改,read,题解,uoj839,id,int,题字
From: https://www.cnblogs.com/Farmer-djx/p/18012466

相关文章

  • 2024大试牛刀5题解
    鼠鼠我鸭没学过前缀和的自己去补一下,这里不过多赘述(其实是我不想写)以第二组数据为例:类型0100体重2565先计算出不使用魔法时鸭鸭的重量,当作基础值\(ori=5\)。然后来看看对一段区间使用魔法会造成什么效果:类型0100体重2565变化a+2-5......
  • ABC338G题解
    也许是一个简单一点的做法?假如我们要求一个表达式的值,我们求的顺序显然是,按照加号划分为若干段,段内只有数字和乘号,计算出段内结果后全部加起来。称一个只有数字和乘号的表达式是基本表达式,我们将每个表达式的贡献拆分为若干个基本表达式之和,那么我们就可以枚举每个基本表达式,算......
  • CF516D Drazil and Morning Exercise 题解
    Description给定一棵\(n\)个点的树,边有边权。定义\(f_x=\max_{i=1}^n\text{dist}(x,i)\)。\(q\)次询问最大的满足\(\max_{x\ins}f_x-\min_{x\ins}f_x\lel\)的连通块\(s\)包含的点数。\(n\le10^5\),\(q\le50\)。Solution这里\(f_u\)显然可以用换......
  • CF1771F Hossam and Range Minimum Query 题解
    题目链接:CF或者洛谷比较不错的题,出现奇数次出现的这种问题,比较容易想到一种运算,那就是异或和运算。如果一个区间上一个数出现偶数次,则它对于异或和的贡献为\(0\),那么很显然,我们维护下区间异或和即可判断一个区间上是否存在出现奇数次的数。然后我们注意到\(1\oplus2\oplu......
  • CF1861E Non-Intersecting Subpermutations 题解
    简要题意一个长度为\(n\)的元素在\([1,k]\)的整数序列\(a\)的价值定义如下。初始\(i=1\),如果\(a_{i\simi+k-1}\)包含了\(1\simk\)的所有整数,则价值加\(1\),然后令\(i=i+k\)。如果没有包含\(1\simk\)的所有整数则\(i=i+1\),直到\(i\geqn-k+2\)时结束。......
  • CF1863F Divide, XOR, and Conquer 题解
    简要题意你有两个指针\(l,r\)初始时\(l=1,r=n\)。你可以操作若干次知道\(l=r\)。每次操作你可以选择一个整数\(k\in[l,r)\),记\(x=\bigoplus_{i=l}^ka_i,y=\bigoplus_{i=k+1}^ra_i\)。如果\(x\leqy\),你可以令\(l=k+1\)。如果\(x\geqy\),你可以令\(r=k\)。......
  • P9663 Permutation on Tree 题解
    考虑枚举一个\(x\in[1,n)\),将\(\leqx\)的看作\(0\),\(>x\)的看作\(1\),那么一个排列的贡献实际上就是\(\sum_{x=1}^{n-1}\sum[[p_i\leqx]+[p_{i+1}>x]=1]\)。那么问题转变为一个给定一棵树,每一个点有权值\(0\)或\(1\),求所有排布方案的贡献之和。设\(f_x\)表示......
  • P9697 Canvas 题解
    首先观察到有一个关键性质是\(1\leqx_i,y_i\leq2\)。那么我们贪心的考虑我们肯定会将\((x,y)=(1,1)\)的在一开始操作,\((x,y)=(2,2)\)的最后操作。也就是说现在没有固定的是\((x,y)=(1,2)\)和\((x,y)=(2,1)\)的。我们不妨令\((x,y)=(1,2)\),然后连边\((l,r)\)。然......
  • P10013 Tree Topological Order Counting 题解
    首先题目里面写了每一个数都有权值,一般这种题只能去想求出每一个的具体方案数,那么也就是我们得求出\(h_{i,j}\)表示在所有合法拓扑序中\(a_i=j\)的方案数。一颗树的拓扑序数量是\(\dfrac{n!}{\prodsiz_i}\),相信大家都知道。因为我们需要保证这一棵树满足拓扑排序的条件,不......
  • P10068 [CCO2023] Line Town 题解
    好题,但是感觉写起来有点屎。题目大意给定一个序列\(a\),你每次可以选择\(i\in[1,n-1]\),交换\(a_i,a_{i+1}\),并且给\(a_i,a_{i+1}\)取相反数。问你最少需要多少次交换才能使得序列非降,可能无解。做法首先考虑给偶数位置初始乘上\(-1\),然后操作变成交换相邻两个数,下面提......