首页 > 其他分享 >2022.10.18 CSP2022 模拟赛五

2022.10.18 CSP2022 模拟赛五

时间:2022-10-18 21:48:13浏览次数:46  
标签:dep cnt int 18 void CSP2022 mi read 2022.10

旅行路线

Source:CF459E。

憨憨题。

按 \(w\) 排序后,考虑 DP,设 \(f_u\) 表示目前在点 \(u\),可以走出的最长路线。

按阶段转移的时候稍微注意一下相同边权的处理,具体的,开一个 \(g_u\) 表示这里的预存答案,然后集体转移就行了。

时间复杂度 \(O(m\log m)\)。

Code
const int N=3e5+5,M=3e5+5,V=1e6+5;
int f[N],g[N],ans;
vector<pii> ed[V];
int main() {
	int n=read(),m=read();
	FOR(i,1,m) {
		int x=read(),y=read(),v=read();
		ed[v].pb(x,y);
	}
	FOR(i,1,V-5) {
		for(pii j:ed[i]) chkmax(g[j.se],f[j.fi]+1);
		for(pii j:ed[i]) chkmax(f[j.se],g[j.se]),g[j.se]=0;
	}
	int ans=0;
	FOR(i,1,n) chkmax(ans,f[i]);
	printf("%d\n",ans);
}

剧毒礼物

Source:「CTSC2017」吉夫特。

显然结论:\(\binom{n}{m} \bmod 2=[n\And m=0]\),证明考虑 Lucas 定理,此处略去。

问题可以转变为寻找最长的子序列满足 \(a_1\supseteq a_2\supseteq a_3\supseteq\ldots\supseteq a_n\),倒过来做,条件就是子集条件,可以直接枚举子集 DP。

时间复杂度 \(O(3^{\log a_i})\)。

Code
int a[N],f[V];
void Add(int &x,int y) {x+=y;if(x>=mod) x-=mod;}
int main() {
	int n=read();
	FOR(i,1,n) a[i]=read();
	reverse(a+1,a+n+1);
	FOR(i,1,n) {
		for(int j=a[i];j;j=(j-1)&a[i]) Add(f[a[i]],f[j]);
		Add(f[a[i]],1);
	}
	int ans=0;
	FOR(i,1,n) Add(ans,f[a[i]]);
	printf("%d\n",(ans-n+mod)%mod);
}

信息网络

Source:CF1270H。

结论一:每个连通块均是一个区间。

证明:设 \(i<j,a_i<a_j\),则在 \([i,j]\) 中的点要么与 \(i\) 有边要么与 \(j\) 有边,可以分类讨论证明,此处不表。

维护区间很困难,我们考虑维护区间交点个数,这个问题等价于求出 \(\min_{i=1}^x a_i>\max_{i=x+1}^n a_i\) 的元素个数,枚举 \(\max_{i=x+1}^n a_i\) 的值,则其能满足上述限制当且仅当将比他大的数设为 \(1\),比他小的数设为 \(0\),序列形如 \(11\ldots1100\ldots00\)。

这个序列的形态看起来就很难维护,考虑维护 \(10\) 段的个数,发现这个很好维护。

于是,按值域建立线段树,维护全局最小值和最小值个数,答案即为最小值个数。

具体的更新,考虑修改 \(x\) 会造成什么样的影响就行了,细节请参照代码。

Code
const int N=5e5+5,V=1e6+5;
int a[N];
int mi[V*4],cnt[V*4],add[V*4];
void pushup(int p) {
    mi[p]=min(mi[p*2],mi[p*2+1]),cnt[p]=0;
    if(mi[p]==mi[p*2]) cnt[p]+=cnt[p*2];
    if(mi[p]==mi[p*2+1]) cnt[p]+=cnt[p*2+1];
}
void pushadd(int p,int v) {mi[p]+=v,add[p]+=v;}
void pushdown(int p) {
    if(add[p]) pushadd(p*2,add[p]),pushadd(p*2+1,add[p]),add[p]=0;
}
void update_cnt(int p,int l,int r,int x,int v) {
    if(l==r) return cnt[p]+=v,void();
    int mid=(l+r)>>1;pushdown(p);
    if(x<=mid) update_cnt(p*2,l,mid,x,v);
    else update_cnt(p*2+1,mid+1,r,x,v);
    pushup(p);
}
void update(int p,int l,int r,int x,int y,int v) {
    if(x<=l&&r<=y) return pushadd(p,v);
    int mid=(l+r)>>1;pushdown(p);
    if(x<=mid) update(p*2,l,mid,x,y,v);
    if(y>mid) update(p*2+1,mid+1,r,x,y,v);
    pushup(p);
}
void work(int x,int v) {update(1,0,1e6,min(a[x],a[x+1]),max(a[x],a[x+1])-1,v);}
int main() {
    int n=read(),q=read();
    int vv=1e6;
    a[0]=vv+1,a[n+1]=0;
    FOR(i,1,n) a[i]=read();
    FOR(i,1,n) update_cnt(1,0,vv,a[i],1);
    FOR(i,0,n) work(i,1);
    FOR(i,1,q) {
        int x=read(),v=read();
        work(x-1,-1),work(x,-1),update_cnt(1,0,vv,a[x],-1);
        a[x]=v;
        work(x-1,1),work(x,1),update_cnt(1,0,vv,a[x],1);
        printf("%d\n",cnt[1]);
    }
}

调兵遣将

Source:「ICPC 2018 WF」Conquer The World

反悔贪心。

考虑从上往下的考虑每一个点作为 LCA 进行一个周转,从 \(x\) 到 \(y\) 的周转的费用是 \(dep_x+dep_y-2*dep_{lca}\)。

选定一个的代价是这么多,选定了之后在 \(x\) 对应的堆中插入 \(-dep_y+2*dep_{lca}\),\(y\) 对应的堆中插入 \(-dep_x+2*dep_{lca}\),用于反悔。

另外我们不能选定两个反悔操作,换句话说,我们希望优先满足真正的周转,我们直接将 \(x\) 插入的东西变成 \(dep_x-inf\),最后的时候加进来就行。

需要支持对的合并,直接使用 pbds 即可。

过掉测试题要树剖模拟费用流,不写。

Code
const int N=250005;
const ll inf=1e13;
vector<pii> G[N];
int a[N],b[N],tot;
__gnu_pbds::priority_queue<ll,greater<ll> > A[N],B[N];
ll ans=0,dep[N];
void dfs(int u,int fa) {
    int cc=abs(a[u]-b[u]);
    if(a[u]<b[u]) while(cc) A[u].push(dep[u]-inf),tot++,cc--;
    else while(cc) B[u].push(dep[u]),cc--;
    for(auto [v,d]:G[u]) if(v!=fa) {
        dep[v]=dep[u]+d,dfs(v,u);
        A[u].join(A[v]),B[u].join(B[v]);
    }
    while(sz(A[u])&&sz(B[u])&&A[u].top()+B[u].top()-2*dep[u]<0) {
        ll t1=A[u].top(),t2=B[u].top();
        A[u].pop(),B[u].pop();
        ans+=t1+t2-2*dep[u];
        A[u].push(-t2+2*dep[u]),B[u].push(-t1+2*dep[u]);
    }
}
int main() {
    int n=read();
    FOR(i,1,n-1) {
        int x=read(),y=read(),c=read();
        G[x].pb({y,c}),G[y].pb({x,c});
    }
    FOR(i,1,n) a[i]=read(),b[i]=read();
    dfs(1,0),printf("%lld\n",ans+inf*tot);
}

标签:dep,cnt,int,18,void,CSP2022,mi,read,2022.10
From: https://www.cnblogs.com/cnyzz/p/16804295.html

相关文章

  • 归档 221018 | 做题记录
    K.Differencehttps://loj.ac/p/2161好耶我会打\(n^3\)!这说明这道题\(n\)一定等于\(10^3\)!我超,是\(10^6\)????寄,,,,,枚举出现次数最多的字符(假设为\(x\))和出现次数最少......
  • 【闲话】2022.10.18
    今天中午是world.execute(me),好欸今天考试本来看完题之后就想着直接爆零得了一点思路都没有,真的要放弃了然后最后还是侥幸切了两道(我跟你说我T1结论是试出来的你......
  • 国标GB28181篇 网闸
    前言   公安网与视频专网之间的视音频传输,大都需要经过网闸,进行透传。网闸包含了防火墙的模块,相对于我们国标服务来说,部署了双网双平台,通过网闸,将视频流从视频专网,推送......
  • 20221018笔记
    初级课程只有10节,所以计划10天看完,一鼓作气嘛,20221016开始,20221025全部看完;之后再进入进阶课程。函数的递归是重中之重!一定要练习,不然等于白学!函数需要学会查询工具的使用:M......
  • 10月18日内容总结——索引取值和迭代取值的差异、模块
    目录一、索引取值和迭代取值的差异二、模块1、简介1.模块的本质2.模块的历史3.python模块的多种表现形式2、模块的分类3、导入模块的两种语法格式1.import模块名2.from名......
  • ubuntu18安装redis后未开机启动Could not connect to Redis at 127.0.0.1:6379: Conne
    阿里云ubuntu18安装redis后,aptinstallredis-serverredis-cli提示CouldnotconnecttoRedisat127.0.0.1:6379:Connectionrefused最终发现是两方面导致:1.ubuntu18......
  • 2022-10-18 uniapp h5端 通过腾讯提供的api并输入对应的经纬度 获取城市
    首先说明一下这是h5端,是的,他娘的h5端。然后先用uni.getLocation(我用的是wgs84)获取到经纬度,什么?你告诉我pc端无法获取,老是报什么网络错误的错误,连手机端也是这样??哦多茄~~......
  • S3C2440 温度传感器ds18b20的焊接测试
    =================================================================================================因为Linux内核3.0自带Dallas1-wires设备驱动,路径为:drivers/w1,所以......
  • HDU1863畅通工程
    畅通工程TimeLimit:1000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):35107    AcceptedSubmission(s):15572......
  • 10.18
    finalshell输入showdatabases;报错HiveExceptionjava.lang.RuntimeException:Unabletoinstantiateorg.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient......