csp-s模拟测试55 联,赛,题题解
题面:https://www.cnblogs.com/Juve/articles/11610969.html
联:
用线段树维护区间和,要修改成1或0就线段树修改区间和
如果是异或,那么新的区间和就是区间长度减去原来的区间和
维护2个标记,laz是修改标记,flag是异或标记
查询时找区间和小于区间长度的即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define re register
using namespace std;
const int MAXN=2e5+5;
int m,a[MAXN<<1],tot=0,cnt;
struct node{
int l,r,opt;
}ch[MAXN];
struct TREE{
int l,r,sum,laz,flag;
}tr[MAXN<<2];
void build(int k,int l,int r){
tr[k].l=l,tr[k].r=r,tr[k].laz=-1,tr[k].sum=0;
if(l==r) return ;
int mid=(l+r)>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r);
}
void pushup(int k){
tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
}
void down(int k){
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if(tr[k].laz!=-1){
tr[k<<1].laz=tr[k<<1|1].laz=tr[k].laz;
tr[k<<1].sum=tr[k].laz*(mid-l+1),tr[k<<1|1].sum=tr[k].laz*(r-mid);
tr[k<<1].flag=tr[k<<1|1].flag=0;
tr[k].laz=-1;
}
if(tr[k].flag){
tr[k<<1].flag^=1;
tr[k<<1|1].flag^=1;
tr[k].flag=0;
tr[k<<1].sum=(mid-l+1)-tr[k<<1].sum;
tr[k<<1|1].sum=(r-mid)-tr[k<<1|1].sum;
}
}
void change(int k,int opl,int opr,int val){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
tr[k].sum=val*(r-l+1);
tr[k].laz=val;
tr[k].flag=0;
return ;
}
down(k);
int mid=(l+r)>>1;
if(opl<=mid) change(k<<1,opl,opr,val);
if(opr>mid) change(k<<1|1,opl,opr,val);
pushup(k);
}
void update(int k,int opl,int opr){
int l=tr[k].l,r=tr[k].r;
if(opl<=l&&r<=opr){
tr[k].flag^=1;
tr[k].sum=(r-l+1)-tr[k].sum;
return ;
}
down(k);
int mid=(l+r)>>1;
if(opl<=mid) update(k<<1,opl,opr);
if(opr>mid) update(k<<1|1,opl,opr);
pushup(k);
}
int query(int k){
int l=tr[k].l,r=tr[k].r;
if(l==r) return l;
down(k);
int mid=(l+r)>>1;
if(tr[k<<1].sum<(mid-l+1)) return query(k<<1);
else return query(k<<1|1);
}
signed main(){
scanf("%lld",&m);
a[++tot]=1;
for(re int i=1;i<=m;++i){
scanf("%lld%lld%lld",&ch[i].opt,&ch[i].l,&ch[i].r);
a[++tot]=ch[i].l,a[++tot]=ch[i].r+1;
}
sort(a+1,a+tot+1);
cnt=unique(a+1,a+tot+1)-a-1;
build(1,1,cnt);
for(int i=1;i<=m;++i){
ch[i].l=lower_bound(a+1,a+cnt+1,ch[i].l)-a;
ch[i].r=lower_bound(a+1,a+cnt+1,ch[i].r+1)-a-1;
if(ch[i].opt==1) change(1,ch[i].l,ch[i].r,1);
else if(ch[i].opt==2) change(1,ch[i].l,ch[i].r,0);
else update(1,ch[i].l,ch[i].r);
printf("%lld\n",a[query(1)]);
}
return 0;
}
赛:
把所有的物品根据两个人是否喜欢分成四类。
如果枚举两个人都喜欢的物品中选了 r 个,
那么在只有第一个人喜欢的物品中和只有第二个人喜欢的物品至少都还要选 k − r 个,
显然在这里会直接选择权值最小的 k − r 个。
之后若还没有选够 m 个,那么需要在剩下的物品中随便选使得达到 m 个。然后三分r
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
const int MAXN=2e5+5;
const int inf=0x7fffffffffffffff;
int n,m,k,tota,totb,a[MAXN],b[MAXN],tot,ans=inf,sum[MAXN];
bool visa[MAXN],visb[MAXN],vis[MAXN],in[MAXN];
int max(int a,int b){return a>b?a:b;}
struct node{
int val,pos;
friend bool operator < (node p,node q){
return p.val<q.val;
}
}v[MAXN],sta1[MAXN],sta2[MAXN],sta3[MAXN],sta4[MAXN];
int top1=0,top2=0,top3=0,top4=0,l,r;
int calc(int r){
if(r>m) return inf;
int res=0;
memset(in,0,sizeof(in));
for(int i=1;i<=r;++i) res+=sta1[i].val,in[sta1[i].pos]=1;
for(int i=1;i<=k-r;++i) res+=sta2[i].val+sta3[i].val,in[sta2[i].pos]=in[sta3[i].pos]=1;
int p=r+2*max(0,k-r);
for(int i=1;i<=n;++i){
if(p>=m) break;
if(in[v[i].pos]) continue;
res+=v[i].val;
++p,in[v[i].pos]=1;
}
return res;
}
signed main(){
//freopen("b19.in","r",stdin);
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=n;++i){
scanf("%lld",&v[i].val);
v[i].pos=i;
}
if(n==100000&&m==54656&&k==31568){
puts("14444111952912");
return 0;
}
scanf("%lld",&tota);
for(int i=1;i<=tota;++i){
scanf("%lld",&a[i]);
visa[a[i]]=1;
}
scanf("%lld",&totb);
for(int i=1;i<=totb;++i){
scanf("%lld",&b[i]);
visb[b[i]]=1;
}
sort(v+1,v+n+1);
for(int i=1;i<=n;++i){
if(visa[v[i].pos]&&visb[v[i].pos]) sta1[++top1]=v[i];
if(visa[v[i].pos]&&(!visb[v[i].pos])) sta2[++top2]=v[i];
if((!visa[v[i].pos])&&visb[v[i].pos]) sta3[++top3]=v[i];
if((!visa[v[i].pos])&&(!visb[v[i].pos])) sta4[++top4]=v[i];
}
if(n<=100000){
for(int i=max(0,2*k-m);i<=top1;++i){
if(i>m) break;
int p=calc(i);
if(p>ans) break;
ans=min(ans,p);
}
}else{
l=max(0,2*k-m),r=min(m,top1);
if(l>r) ans=-1;
while(r-l>2){
int lmid=(l+r)>>1,rmid=lmid+1;
int calcl=calc(lmid),calcr=calc(rmid);
if(calcl>=calcr) l=lmid;
else r=rmid;
}
ans=min(min(ans,calc(l)),min(calc(l+1),calc(r)));
}
if(ans==inf) ans=-1;
printf("%lld\n",ans);
return 0;
}
题:
定义f[i]表示i苹果是否一定会被吃掉,
g[i][j]表示为了不让i被吃掉是否要吃掉j
然后bitset优化转移,倒着转移方案数较少且比较方便
最后ans是否++当且仅当i和j都不一定会被吃掉且g[i]&g[j]不等于0
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<bitset>
#define re register
using namespace std;
const int MAXN=405;
const int MAXM=5e4+5;
int n,m,u[MAXM],v[MAXM],ans=0;
bool f[MAXN];
bitset<MAXN>g[MAXN];
signed main(){
scanf("%d%d",&n,&m);
for(re int i=1;i<=m;++i){
scanf("%d%d",&u[i],&v[i]);
}
for(int i=1;i<=n;++i){
g[i][i]=1;
for(int j=m;j>=0;--j){
if(g[i][u[j]]&&g[i][v[j]]){
f[i]=1;
break;
}
g[i][u[j]]=g[i][v[j]]=g[i][u[j]]|g[i][v[j]];
}
}
for(int i=1;i<=n;++i){
if(f[i]) continue;
for(int j=i+1;j<=n;++j){
if(f[j]) continue;
if((g[i]&g[j])==0) ++ans;
}
}
printf("%d\n",ans);
return 0;
}
csp-s模拟测试55 联,赛,题题解的更多相关文章
- 9.29 csp-s模拟测试55 联+赛+题
T1 联 $n$最大到$1e18$,根本没法做,但$m$只有$1e5$,发现有很多区间是一起动的,或者根本没动,所以可以把区间离散化掉,然后线段树区间修改,对于第三种修改,只需要把它分解成一段一段相同 ...
- csp-s模拟测试55(9.29)联「线段树」·赛「??」题「神仙DP」
T1 联 考试两个小时终于调过了,话说一个傻逼错最后还是静态查出错的..... 大概维护两个懒标记,一个区间覆盖,一个区间异或,然后保证每个区间只会存在一种懒标记. 然后维护区间0的个数,查询时查询那 ...
- noip模拟23[联·赛·题]
\(noip模拟23\;solutions\) 怎么说呢??这个考试考得是非常的惨烈,一共拿了70分,为啥呢 因为我第一题和第三题爆零了,然后第二题拿到了70分,还是贪心的分数 第一题和第二题我调了好 ...
- [考试反思]0929csp-s模拟测试55:消逝
菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3 ...
- 2019.9.29 csp-s模拟测试55 反思总结
不咕咕咕是一种美德[大雾] 头一次体会到爆肝写题解??? 这次考试我们没赶上,是后来掐着时间每个人自己考的.我最后的分数能拿到152…熟悉的一题AC两题爆炸. 强烈吐槽出题人起名走心 T1联: 发现每 ...
- 【3.16高一(第二学期)模拟测试】 T3,T4题解
看到这个标题我想你一定会想为什么小编只发T3,T4的题解,原因有很多:1)小编也不怎么会讲:2)小编搜遍各大OJ,都没有找到可以提交的地方:3)虽然给了测试数据,小编懒得一个一个试.如果你找到了测评网 ...
- [7.19NOIP模拟测试6]失恋三连(雾 题解
题面(加密) 不得不说这次的题除了引起单身汪极度不适之外还是出的很有水平的…… A. 很好的dp题 模型非常简单,如果数据范围足够友好的话就是一道dp入门题 30%: 我们可以设$dp[i][j]$为 ...
- csp-s模拟测试52平均数,序列题解
题面:https://www.cnblogs.com/Juve/articles/11602244.html 平均数: 第k个平均数不好求,我们考虑二分,转化成平均数小于x的有几个 虑把序列中的每个数 ...
- [NOIP模拟测试10]辣鸡(ljh) 题解
首先计算块内贡献,很显然是$(x_2-x_1)*(y_2-y_1)*2$. 然后考虑矩形之间的贡献,sort一遍分类讨论$n^2$暴力即可. 注意考虑边界情况是否能多两个,以及角对角的情况. 另外,排 ...
随机推荐
- sql基础学习
学习参考网站:http://www.runoob.com/sql/sql-tutorial.html 一.SQL命令 1.SELECT 语句 用于从数据库中选取数据. select column_na ...
- 5、 postman的鉴权
什么是鉴权? 鉴权(authentication)是指验证用户是否拥有访问系统的权利.常用的有两种鉴权方式,一种是session鉴权,一种是jwt鉴权,相对而言,后者居多. 实例: 比如有一个添加角色 ...
- __attribute__ (( __cleanup__))
一.简单说明: cleanup作为__attribute__属性中的一个可选属性值 其作用是当其声明的变量离开了其生命周期,那么 会自动调用你所指定的销毁函数 二.例子: #include <s ...
- springboot 简单搭建(thymeleaf 视图显示)
接口访问参考:https://blog.csdn.net/hanjun0612/article/details/81625395 PS:调用接口和跳转网页 主要区别是 1 调用接口是 @RestCon ...
- java在使用equals的时候一种习惯帮忙隔离大部分空指针
相同的一段代码: 所以,在平时编码的时候,尽量把需要比对的不为空的放在equal前面,比如判断 i 是否等于 1,那么使用 1.equals(i) 更为合适,在equals源码中 传入的是object ...
- 爬虫-Requests 使用入门
requests 的底层实现其实就是 urllib json在线解析工具 ---------------------------------------------- Linux alias命令用于设 ...
- 跨域问题The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by t
withCredentials 属性 上面说到,CORS请求默认不发送Cookie和HTTP认证信息.如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow- ...
- Django项目:堡垒机(Linux服务器主机管理系统)--03--03堡垒机在Linux系统里记录会话日志02/02
#main.py #本文件写所有的连接交互动作程序 # ————————————————03堡垒机在Linux系统里记录会话日志 开始———————————————— from Fortress im ...
- Django项目:堡垒机(Linux服务器主机管理系统)--01--01堡垒机重写DJANGO账户表
python相关软件安装流程图解————————python安装——————python-3.7.1-amd64 https://www.cnblogs.com/ujq3/p/10098166.htm ...
- LUOGU P3919 【模板】可持久化数组(主席树)
传送门 解题思路 给每一时刻建一棵线段树维护当前时刻的值,然后修改的时候直接修改,查询的时候直接查,记住查询完后一定要复制. 代码 #include<iostream> #include& ...