2019.9.29 csp-s模拟测试55 反思总结
不咕咕咕是一种美德【大雾】
头一次体会到爆肝写题解???
这次考试我们没赶上,是后来掐着时间每个人自己考的。我最后的分数能拿到152…熟悉的一题AC两题爆炸。
强烈吐槽出题人起名走心
T1联:
发现每一次加入一个区间的操作,只有区间的l或者r+1有可能成为答案。那么考虑能不能用这两个点代表一整个区间,维护全局最靠左的0在什么地方。
把每个操作的l和r+1都存下来,离散化,建一棵线段树。每一次区间操作都针对线段树上的a[l]-a[r+1]-1这部分(a[x]为x离散化以后的排序,即线段树里的位置)。
维护线段树的区间和,每一次查询就是寻找最左边的区间和不等于区间长度的地方。对于反转操作,打一个可下传的标记,让现有区间和变成区间长度减去原区间和。
要注意一开始答案为1,保存下所有l和r+1还要额外加一个1。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,cnt=;
long long b[];
struct node{
int opt;
long long l,r;
}a[];
struct tree{
int l,r,sum,tag1,tag2;
}t[];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
t[p].tag1=-;
if(l==r)return;
int mid=(l+r)/;
build(p*,l,mid);
build(p*+,mid+,r);
}
void pushdown(int p){
if(t[p].tag1!=-){
t[p*].tag1=t[p].tag1;
t[p*].sum=(t[p*].r-t[p*].l+)*t[p].tag1;
t[p*].tag2=;
t[p*+].tag1=t[p].tag1;
t[p*+].sum=(t[p*+].r-t[p*+].l+)*t[p].tag1;
t[p*+].tag2=;
t[p].tag1=-;
}
if(t[p].tag2){
t[p*].tag2^=;
t[p*].sum=t[p*].r-t[p*].l+-t[p*].sum;
t[p*+].tag2^=;
t[p*+].sum=t[p*+].r-t[p*+].l+-t[p*+].sum;
t[p].tag2=;
}
}
void change(int p,int l,int r,int val){
if(l<=t[p].l&&t[p].r<=r){
t[p].sum=(t[p].r-t[p].l+)*val;
t[p].tag1=val;
t[p].tag2=;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/;
if(l<=mid)change(p*,l,r,val);
if(r>mid)change(p*+,l,r,val);
t[p].sum=t[p*].sum+t[p*+].sum;
}
void change1(int p,int l,int r){
if(l<=t[p].l&&t[p].r<=r){
t[p].tag2^=;
t[p].sum=t[p].r-t[p].l+-t[p].sum;
return;
}
pushdown(p);
int mid=(t[p].l+t[p].r)/;
if(l<=mid)change1(p*,l,r);
if(r>mid)change1(p*+,l,r);
t[p].sum=t[p*].sum+t[p*+].sum;
}
long long query(int p){
if(t[p].l==t[p].r){
return b[t[p].l];
}
pushdown(p);
int mid=(t[p].l+t[p].r)/;
long long val;
if(t[p*].sum!=t[p*].r-t[p*].l+)val=query(p*);
else if(t[p*+].sum!=t[p*+].r-t[p*+].l+)val=query(p*+);
t[p].sum=t[p*].sum+t[p*+].sum;
return val;
}
int main()
{
scanf("%d",&m);
b[]=;
for(int i=;i<=m;i++){
scanf("%d%lld%lld",&a[i].opt,&a[i].l,&a[i].r);
a[i].r++;
b[++cnt]=a[i].l;
b[++cnt]=a[i].r;
}
sort(b+,b+cnt+);
int n=unique(b+,b+cnt+)-b-;
build(,,n);
for(int i=;i<=m;i++){
a[i].l=lower_bound(b+,b+n+,a[i].l)-b;
a[i].r=lower_bound(b+,b+n+,a[i].r)-b;
if(a[i].opt==)change(,a[i].l,a[i].r-,);
else if(a[i].opt==)change(,a[i].l,a[i].r-,);
else change1(,a[i].l,a[i].r-);
printf("%lld\n",query());
}
return ;
}
T2赛:
考试的时候错误贪心骗到了40分…
正解是枚举满足两个人都喜欢的物品的个数x,然后对于每个人再补上k-x个他喜欢的物品,不足m个就再从剩下的物品里补全。用线段树维护剩下的物品以支持查询前多少个最小值的和。
注意边界问题。
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int n,m,k,A,B,cnt,k1,k2;
int v[],v1[],va[],vb[],val[];
int a[],b[],ab[],d[];
long long sum,ans=1e18,suma[],sumb[],sumab;
struct node{
int l,r,cnt;
long long sum;
}t[];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r)return;
int mid=(l+r)/;
build(p*,l,mid);
build(p*+,mid+,r);
}
void change(int p,int l,int r,int y){
if(l<=t[p].l&&t[p].r<=r){
t[p].cnt+=y;
t[p].sum+=y*(val[l]);
return;
}
int mid=(t[p].l+t[p].r)/;
if(l<=mid)change(p*,l,r,y);
if(r>mid)change(p*+,l,r,y);
t[p].cnt=t[p*].cnt+t[p*+].cnt;
t[p].sum=t[p*].sum+t[p*+].sum;
}
long long query(int p,int y){
if(t[p].l==t[p].r){
return t[p].sum/t[p].cnt*y;
}
// int mid=(t[p].l+t[p].r)/2;
if(t[p*].cnt>y)return query(p*,y);
else if(t[p*].cnt==y)return t[p*].sum;
else{
long long z=;
z+=t[p*].sum;
return z+query(p*+,y-t[p*].cnt);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++){
scanf("%d",&v[i]);
val[++cnt]=v[i];
}
sort(val+,val+cnt+);
int num=unique(val+,val+cnt+)-val-;
scanf("%d",&A);
for(int i=,x;i<=A;i++){
scanf("%d",&x);
va[x]=;
}
scanf("%d",&B);
for(int i=,x;i<=B;i++){
scanf("%d",&x);
vb[x]=;
}
if(A<k||B<k||k>m||n<m){
printf("-1");
return ;
}
for(int i=;i<=n;i++){
v1[i]=lower_bound(val+,val+num+,v[i])-val;
if(va[i]&&vb[i]){
ab[++ab[]]=v1[i];
}
else if(va[i]){
a[++a[]]=v1[i];
}
else if(vb[i]){
b[++b[]]=v1[i];
}
else d[++d[]]=v1[i];
}
if(k*-ab[]>m){
printf("-1");
return ;
}
build(,,num);
sort(ab+,ab+ab[]+);
sort(a+,a+a[]+);
sort(b+,b+b[]+);
sort(d+,d+d[]+);
for(int i=;i<=a[];i++){
suma[i]=suma[i-]+val[a[i]];
if(i>k)change(,a[i],a[i],);
}
for(int i=;i<=b[];i++){
sumb[i]=sumb[i-]+val[b[i]];
if(i>k)change(,b[i],b[i],);
}
// for(int i=1;i<=ab[0];i++){
// change(1,ab[i],ab[i],1);
// }
for(int i=;i<=d[];i++){
change(,d[i],d[i],);
}
for(int i=;i<=min(ab[],k);i++){
if(*k-m>i||k-i>a[]||k-i>b[]){
if(i>){
// change(1,ab[i],ab[i],-1);
sumab+=val[ab[i]];
if(a[k-i+])change(,a[k-i+],a[k-i+],);
if(b[k-i+])change(,b[k-i+],b[k-i+],);
}
}
else if(i==){
sum=suma[k]+sumb[k];
sum+=query(,m-*k);
ans=min(sum,ans);
}
else{
// change(1,ab[i],ab[i],-1);
sumab+=val[ab[i]];
if(a[k-i+])change(,a[k-i+],a[k-i+],);
if(b[k-i+])change(,b[k-i+],b[k-i+],);
sum=sumab+suma[k-i]+sumb[k-i];
sum+=query(,m-i-*(k-i));
ans=min(ans,sum);
}
}
printf("%lld\n",ans);
return ;
}
T3题:
对于每个苹果,考虑它如果要存活下来需要满足哪些条件,求出它如果存活需要ban掉的苹果的集合。最后统计答案,枚举两个苹果,如果它们都有机会存活且存活需要ban掉的集合没有交集,那么答案++。
于是一开始假设一个苹果最后活着,从后往前逆推出需要满足的集合。逆推的意义为,若要让现有集合存活到这个操作之后,需要让前面的集合满足什么样子。
如果一个操作的两个苹果都属于现有集合,那么作为目标存活到最后的苹果显然必死。如果一个操作中有一个苹果属于现有集合,那么为了让这个苹果存活下来以满足后面的操作,另一个苹果肯定属于这个操作之前的集合。
考试的时候想到了集合也想到了逆推,愣是没搞出来怎么写,大约是含义还有不明确的地方。
#include<iostream>
#include<cstdio>
#include<bitset>
#include<cstring>
using namespace std;
int n,m,vis[],flag,ans,x[],y[],num;
bitset<>a[];
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d",&x[i],&y[i]);
}
for(int i=;i<=n;i++){
a[i][i]=;
for(int j=m;j>=;j--){
int u=x[j],v=y[j];
if(a[i][u]&&a[i][v]){
vis[i]=;
break;
}
else if(a[i][u]||a[i][v]){
a[i][u]=a[i][v]=;
}
}
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
if(!vis[i]&&!vis[j]&&(a[i]&a[j]).count()==)ans++;
}
}
printf("%d",ans);
return ;
}
几次考试暴露出来的问题越来越多,有点应付不过来。
趁着国庆集训赶紧追进度…不然怕是真的要在一个多月以后彻底结束了。
2019.9.29 csp-s模拟测试55 反思总结的更多相关文章
- 2019.8.3 [HZOI]NOIP模拟测试12 C. 分组
2019.8.3 [HZOI]NOIP模拟测试12 C. 分组 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 刚看这题觉得很难,于是数据点分治 k只有1和2两种,分别 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)
2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...
- 2019.8.14 NOIP模拟测试21 反思总结
模拟测试20的还没改完先咕着 各种细节问题=错失190pts T1大约三分钟搞出了式子,迅速码完,T2写了一半的时候怕最后被卡评测滚去交了,然后右端点没有初始化为n…但是这样还有80pts,而我后来还 ...
- 2019.8.9 NOIP模拟测试15 反思总结
日常爆炸,考得一次比一次差XD 可能还是被身体拖慢了学习的进度吧,虽然按理来说没有影响.大家听的我也听过,大家学的我也没有缺勤多少次. 那么果然还是能力问题吗……? 虽然不愿意承认,但显然就是这样.对 ...
- 2019.8.1 NOIP模拟测试11 反思总结
延迟了一天来补一个反思总结 急匆匆赶回来考试,我们这边大家的状态都稍微有一点差,不过最后的成绩总体来看好像还不错XD 其实这次拿分的大都是暴力[?],除了某些专注于某道题的人以及远程爆踩我们的某学车神 ...
- 2019.7.29 NOIP模拟测试10 反思总结【T2补全】
这次意外考得不错…但是并没有太多厉害的地方,因为我只是打满了暴力[还没去推T3] 第一题折腾了一个小时,看了看时间先去写第二题了.第二题尝试了半天还是只写了三十分的暴力,然后看到第三题是期望,本能排斥 ...
- 9.29 csp-s模拟测试55 联+赛+题
T1 联 $n$最大到$1e18$,根本没法做,但$m$只有$1e5$,发现有很多区间是一起动的,或者根本没动,所以可以把区间离散化掉,然后线段树区间修改,对于第三种修改,只需要把它分解成一段一段相同 ...
- 2019.10.29 csp-s模拟测试93 反思总结
T1: 求出前缀和,三维偏序O(nlog2n)CDQ 二维其实就可以 #include<iostream> #include<cstdio> #include<cstri ...
随机推荐
- 二分图——多重匹配模板hdu1669
好像多重匹配一般是用网络流来做的.. 这是匈牙利算法的模板:lim是每个组的上界 思路是每个组都可以匹配lim个点,那么当点x遇到的组匹配的点数还没有超过lim时,直接匹配即可 如果已经等于了lim, ...
- 二分+2-sat——hdu3062
hdu3622升级版 注意要保留两位小数 /* 给定n对圆心(x,y),要求从每对里找到一个点画圆,不可相交 使得最小半径最大 二分答案,设最小半径为r 然后两两配对一次进行判断,在2-sat上连边即 ...
- l洛谷 NOIP提高组模拟赛 Day2
传送门 ## T1 区间修改+单点查询.差分树状数组. #include<iostream> #include<cstdio> #include<cstring> ...
- Vue.js项目部署到服务器
1.申请服务器 2.配置Xshell 3.在服务器手动建自己的根目录,把根目录的文件名复制给项目里面config下面的index.js 4.项目开始打包 npm run build 5.打包完成之后把 ...
- 《DSP using MATLAB》Problem 8.29
来汉有一月,往日的高温由于最近几个台风沿海登陆影响,今天终于下雨了,凉爽了几个小时. 接着做题. %% ------------------------------------------------ ...
- java基础之final关键字
final: 意为终态.在java中得注意以下四点: 1.final是一个修饰符,可修饰变量,方法,类. 2.final修饰子类不可以被继承. 3.final修饰的方法不可以被重写(覆盖) 4.对于一 ...
- Python学习day08-python进阶(2)-内置方法
Python学习day08-python进阶(2)-内置方法 列表数据类型内置方法 作用 描述多个值,比如爱好 定义方法 xxxxxxxxxx 2 1 hobby_list ...
- @Value取值为NULL的解决方案
在spring mvc架构中,如果希望在程序中直接使用properties中定义的配置值,通常使用一下方式来获取: @Value("${tag}") private String ...
- [Bzoj3696]化合物【暴力+树形Dp】
Online Judge:Bzoj3696 Label:暴力,树形Dp 题目描述 首长NOI惨跪,于是去念文化课了.现在,他面对一道化学题. 这题的来源是因为在一个奇怪的学校两个化竞党在玩一个奇怪的博 ...
- Android 开发 防止按键连续点击
前言 按键防止连续点击是任何一个项目都要考虑的功能.下面我们将介绍几种防止按键连续点击的方法 用工具类实现 /** *@content:按键延时工具类,用于防止按键连点 *@time:2019-5-1 ...