[問題の解決策]毒性腫瘍に関するOIブラシの質問の概要[SCOI2011]
質問の順序は明確ではないため、\(\ text {BZOJ} \)に従って配置されています。
小学生のグラフ理論委員会、データ構造の脂肪問題、吐き気シミュレーション、腫瘍プラグ\(dp \)、2つの死んだ質問、私はTATを乾燥させます...
【1日目T1】キャンディー
ポータル:キャンディー\(\ text {[P3275]} \) \(\ text {[Bzoj2330]} \)
【タイトル説明】
与えられた(M \)\ \((M \ leqslant 10 ^ 5)\)の制約条件は、以下の条件に(5 \)\種:
\(1 \ x \ y:\) \(A [x] = A [y] \)
\(2 \ x \ y:\) \(A [x] <A [y] \)
\(3 \ x \ y:\) \(A [x] \ geqslant A [y] \)
\(4 \ x \ y:\) \(A [x]> A [y] \)
\(5 \ x \ y:\) \(A [x] \ leqslant A [y] \)
ここで、長さ\(n \) \((n \ leqslant 10 ^ 5)\)の正当なシーケンス\(A \)を作成する必要があります。これにより、シーケンス内の数値の合計が最小になり、解がない場合はこの最小値を出力します\(-1 \)。
【分析】
違いの制約されたボードの質問について言うことは何もありません、そして、激しくサイドを構築して逃げます(SPFA \)、それは合格します。
時間の複雑さ:\(O(SPFA)\)。
【コード】
#include<cstring>
#include<cstdio>
#include<queue>
#define Re register int
using namespace std;
const int N=1e5+5,M=3e5+5,inf=2e9;
int x,y,n,m,o,op,chu[N],dis[N],pan[N],head[N];long long ans;
struct QAQ{int w,to,next;}a[M];queue<int>Q;
inline void add(Re x,Re y,Re z){a[++o].to=y,a[o].w=z,a[o].next=head[x],head[x]=o;}
inline void in(Re &x){
Re fu=0;x=0;char ch=getchar();
while(ch<'0'||ch>'9')fu|=ch=='-',ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x=fu?-x:x;
}
inline int SPFA(Re st,Re ed){//求最小值跑最长路
for(Re i=0;i<=n;++i)dis[i]=-inf,chu[i]=0;
dis[st]=0,chu[st]=pan[st]=1,Q.push(st);
while(!Q.empty()){
x=Q.front(),Q.pop();
pan[x]=0;
for(Re i=head[x],to;i;i=a[i].next)
if(dis[to=a[i].to]<dis[x]+a[i].w){
dis[to]=dis[x]+a[i].w;
if((chu[to]=chu[x]+1)>n+1)return 1;
if(!pan[to])pan[to]=1,Q.push(to);
}
}
return 0;
}
int main(){
in(n),in(m);
for(Re i=n;i>=1;--i)add(0,i,1); //a[i]>=a[0]=1,a[i]-a[0]>=1
while(m--){
in(op),in(x),in(y);
if(op<2)add(y,x,0),add(x,y,0);//a[x]==a[y]: a[x]-a[y]>=0且a[y]-a[x]>=0
else if(op<3)add(x,y,1);//a[x]<a[y]: a[y]-a[x]>=1
else if(op<4)add(y,x,0);//a[x]>=a[y]: a[x]-a[y]>=0
else if(op<5)add(y,x,1);//a[x]>a[y]: a[x]-a[y]>=1
else add(x,y,0);//a[x]<=a[y]: a[y]-a[x]>=0
if(!(op%2)&&x==y){puts("-1");return 0;}
}
if(SPFA(0,n))puts("-1");
else{
for(Re i=1;i<=n;++i)ans+=dis[i];
printf("%lld",ans);
}
}
【Day1 T2】フロア
ポータル:床\(\ text {[P3272]} \) \(\ text {[Bzoj2331]} \)
【タイトル説明】
少し。
【分析】
最初にささやく\(dp \)を差し込まないでください。
【コード】
不知道这儿能放啥,干脆买个萌吧(⊙ω⊙)
[Day1 T3]植物とゾンビ
ポータル:植物対ゾンビ\(\ text {[P3274]} \) \(\ text {[Bzoj2332]} \)
【タイトル説明】
少し。
【分析】
腫瘍ネットワーク腫瘍のようです。
締め切りはありません。
【コード】
不知道这儿能放啥,干脆买个萌吧(⊙ω⊙)
【Day2 T1】トリッキーな操作
ポータル:トリッキーな操作\(\ text {[P3273]} \) \(\ text {[Bzoj2333]} \)
【タイトル説明】
そこ\(N- \) \((N- \ leqslant。3. 5 * 10 ^)\)最初のポイントと通信しない、\(I \)右のノード値\(a_iを\)は、与えられる(\ m \) \((m \ leqslant 3 * 10 ^ 5)\)演算、演算は次のとおりです。
-
\(U \ x \ y:\)はノード\(x \)とノード\(y \)を接続するエッジを追加します。
-
\(A1 \ x \ v:\)ノードの重みを増やします\(x \)\(v \)。
-
\(A2 \ x \ v:\)は、ノード\(x \)が配置されている接続ブロック内のすべてのノードの重みを増やします\(v \)。
-
\(A3 \ v:\)すべてのノードの重みを増やします\(v \)。
-
\(F1 \ x:\)出力ノードの重み\(x \)。
-
\(F2 \ x:\)出力ノード\(x \)が配置されている接続ブロックの最大重み。
-
\(F3:\)すべてのノードの最大の重みを出力します。
【分析】
Bingcha Jiの前処理+ラインツリーがいじり回っています。
接続されたエッジのみがあり、壊れたエッジはないため、すべてのノードの番号付けされた配置を見つけることができ、同じ接続ブロック内のポイントは常に連続した番号付けされた間隔になります。
後退可能なランクを記述し、Bingcha Jiをマージして数値を前処理し、ラインツリーを使用して維持します。
時間の複雑さ:\(O(m \ log n)\)。
【コード】
#include<algorithm>
#include<cstdio>
#include<stack>
#define LL long long
#define Re register int
using namespace std;
const int N=3e5+3,inf=2e9;
int n,T,O,A[N],id[N],idx[N];
struct QAQ{int x,y;char op[5];}a[N];
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
int fa[N],size[N];
struct QWQ{int x,fa,size;};stack<QWQ>Q;
inline int find(Re x){return fa[x]==x?x:find(fa[x]);}
inline void merge(Re x,Re y){
if((x=find(x))==(y=find(y)))return;
if(size[x]<size[y])swap(x,y);
Q.push((QWQ){y,x,size[y]});
fa[y]=x,size[x]+=size[y];
}
inline void sakura(Re o){
if(o>T){
for(Re i=1;i<=n;++i)if(!id[find(i)])
id[find(i)]=++O,O+=size[find(i)]-1;
return;
}
Re tmp=Q.size();
if(a[o].op[0]=='U')merge(a[o].x,a[o].y);
sakura(o+1);
if(Q.size()!=tmp){
QWQ a=Q.top();Q.pop();
fa[a.x]=a.x,size[a.fa]-=(size[a.x]=a.size);
id[a.x]=id[a.fa]+size[a.fa];
}
}
struct Segment_Tree{
#define pl (p<<1)
#define pr (p<<1|1)
#define mid ((L+R)>>1)
struct QAQ{int max,add;}tr[N<<2];
inline void build(Re p,Re L,Re R){
if(L==R){tr[p].max=A[idx[L]];return;}
build(pl,L,mid),build(pr,mid+1,R);
tr[p].max=max(tr[pl].max,tr[pr].max);
}
inline void updata(Re p,Re v){tr[p].max+=v,tr[p].add+=v;}
inline void pushdown(Re p){
if(tr[p].add)updata(pl,tr[p].add),updata(pr,tr[p].add),tr[p].add=0;
}
inline void change(Re p,Re L,Re R,Re l,Re r,Re v){
if(l<=L&&R<=r){updata(p,v);return;}
pushdown(p);
if(l<=mid)change(pl,L,mid,l,r,v);
if(r>mid)change(pr,mid+1,R,l,r,v);
tr[p].max=max(tr[pl].max,tr[pr].max);
}
inline int ask(Re p,Re L,Re R,Re l,Re r){
if(l<=L&&R<=r)return tr[p].max;
Re ans=-inf;pushdown(p);
if(l<=mid)ans=max(ans,ask(pl,L,mid,l,r));
if(r>mid)ans=max(ans,ask(pr,mid+1,R,l,r));
return ans;
}
}TR;
#define op0 a[i].op[0]
#define op1 a[i].op[1]
int main(){
// freopen("123.txt","r",stdin);
in(n);
for(Re i=1;i<=n;++i)in(A[i]),fa[i]=i,size[i]=1;
in(T);
for(Re i=1;i<=T;++i){
scanf("%s",a[i].op);
if(a[i].op[0]=='F'&&a[i].op[1]=='3')continue;
in(a[i].x);
if(a[i].op[0]=='U'||(a[i].op[0]=='A'&&a[i].op[1]!='3'))in(a[i].y);
}
sakura(1);
for(Re i=1;i<=n;++i)idx[id[i]]=i;
TR.build(1,1,n);
for(Re i=1,dlt=0;i<=T;++i){
if(op0=='U')merge(a[i].x,a[i].y);
else if(op0=='A'){
if(op1=='1')TR.change(1,1,n,id[a[i].x],id[a[i].x],a[i].y);
else if(op1=='2')a[i].x=find(a[i].x),TR.change(1,1,n,id[a[i].x],id[a[i].x]+size[a[i].x]-1,a[i].y);
else dlt+=a[i].x;
}
else{
if(op1=='1')printf("%d\n",dlt+TR.ask(1,1,n,id[a[i].x],id[a[i].x]));
else if(op1=='2')a[i].x=find(a[i].x),printf("%d\n",dlt+TR.ask(1,1,n,id[a[i].x],id[a[i].x]+size[a[i].x]-1));
else printf("%d\n",dlt+TR.tr[1].max);
}
}
}
[2日目T2]ミラー分割
ポータル:ミラー分割\(\ text {[P3276]} \) \(\ text {[Bzoj2334]} \)
【タイトル説明】
少し。
【分析】
デジタル腫瘍\(dp \)のようです。
締め切りはありません。
【コード】
不知道这儿能放啥,干脆买个萌吧(⊙ω⊙)
[Day2 T3]ダーツ
ポータル:ダーツ\(\ text {[P3277]} \) \(\ text {[Bzoj2335]} \)
【タイトル説明】
少し。
【分析】
数学の腫瘍シミュレーションの問題、嫌な、したくない。
【コード】
不知道这儿能放啥,干脆买个萌吧(⊙ω⊙)