cd DS
Ice-cream Tycoo(SGU 311)
题目大意
商店里初始时没有物品,支持以下两种操作
- 增加
个价格 的物品 - 对于一名想用
元钱购买前 便宜的物品的顾客,若这些物品总价不超过 则从商店中移除,否则不做操作,报告是否进行了操作
思路
我们可以以价格为端点植一颗线段树,存储有多少个是这个价格的物品,对于第一个我们直接在
对于第二种我们先把不可以的解决了:能发现是如果总数小于
#include<bits/stdc++.h> #define ll long long #define mm 1000010 #define int long long using namespace std; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x*f; } int p[mm*3],sum[mm*3]; ll a[mm]; void push(int x) { p[x]=p[x<<1]+p[x<<1|1]; sum[x]=sum[x<<1]+sum[x<<1|1]; } void updata(int l,int r,int pd,int u,int x) { if(l==r) { p[x]+=u; sum[x]+=1LL*u*l; return ; } int mid=(l+r)>>1; if(pd<=mid) updata(l,mid,pd,u,x<<1); else updata(mid+1,r,pd,u,x<<1|1); push(x); } ll ask_sum(int l,int r,int u,int x) { if(l==r) return 1LL*l*u; int mid=(l+r)>>1; if(u<=p[x<<1]) return (ll)ask_sum(l,mid,u,x<<1); else return (ll)sum[x<<1]+ask_sum(mid+1,r,u-p[x<<1],x<<1|1); } int ask_id(int l,int r,int x) { if(l==r) return l; int mid=(l+r)>>1; if(p[x<<1]) return ask_id(l,mid,x<<1); else return ask_id(mid+1,r,x<<1|1); } void ARRIVE(int x,int y) { a[y]+=x; updata(1,1000000,y,x,1); } void BUY(int n,int y) { if(n>p[1]) { puts("UNHAPPY"); return ; } if((ll)ask_sum(1,1000000,n,1)>y) { puts("UNHAPPY"); return ; } puts("HAPPY"); while(n) { int id=ask_id(1,1000000,1); int x=min(n*1LL,a[id]); updata(1,1000000,id,-x,1); a[id]-=x,n-=x; } } signed main() { ios::sync_with_stdio(0); cin.tie(0); string s; while(cin>>s) { int x,y; cin>>x>>y; if(s[0]=='A') ARRIVE(x,y); else BUY(x,y); } return 0; }
New Year and Conference(CF1284D)
题目大意
给
思路
可以发现如果不存在任何一对讲座在一个场地中冲突,另一场地不冲突,那么就不会存在一个子集的讲座不合法,反之则一定存在不合法的子集。所以我们只需求正确性即可,哈希即可。
#include<bits/stdc++.h> #define ll long long #define ull unsigned long long #define mm 100010 using namespace std; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x*f; } struct node{ int u,id,k; node() {} node(int u, int id, int k):u(u),id(id),k(k){} friend bool operator <(node a,node b) { if(a.u==b.u) return a.k<b.k; return a.u<b.u; } }a1[mm],a2[mm]; ull v[mm],s[mm]; int n; int main() { n=read(); srand(time(0)); for(int i=1;i<=n;i++) { v[i]=(ull)rand()<<31|rand(); a1[i*2-1]=node(read(),i,0); a1[i<<1]=node(read(),i,1); a2[i*2-1]=node(read(),i,0); a2[i<<1]=node(read(),i,1); } n*=2; sort(a1+1,a1+n+1); sort(a2+1,a2+n+1); ull x=0; for(int i=1;i<=n;i++) if(a1[i].k) x^=v[a1[i].id]; else s[a1[i].id]^=x; x=0; for(int i=n;i>=1;i--) if(!a1[i].k) x^=v[a1[i].id]; else s[a1[i].id]^=x; x=0; for(int i=1;i<=n;i++) if(a2[i].k) x^=v[a2[i].id]; else s[a2[i].id]^=x; x=0; for(int i=n;i>=1;i--) if(!a2[i].k) x^=v[a2[i].id]; else s[a2[i].id]^=x; int flag=0; for(int i=1;i<=n/2;i++) flag|=s[i]>0; if(flag==0) puts("YES"); else puts("NO"); return 0; }
New Year Tree(CF620E)
题目大意
给一棵树,现在每个节点上有一个颜色(<=60),有一些查询:
- 把一个子树中所有的节点都赋成同样的颜色
- 求出一个子树中出现过的颜色个数
思路
我们如果直接在树上进行操作显然非常麻烦,所以我们先求出这棵树的
#include<bits/stdc++.h> #define ll long long #define mm 400010 using namespace std; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); } return x*f; } vector<int> e[mm]; bitset<64> tree[mm<<2]; int n,m; int id[mm],idx[mm],cnt; int siz[mm]; int a[mm],lazy[mm<<2]; void dfs1(int x,int f) { siz[x]=1; id[x]=++cnt,idx[cnt]=x; for(auto u:e[x]) { if(u==f) continue; dfs1(u,x); siz[x]+=siz[u]; } } void push(int x){tree[x]=tree[x<<1]|tree[x<<1|1];} void mark(int x,int k) { lazy[x]=k; tree[x].reset(); tree[x].set(k); } void pushdown(int l,int r,int x) { if(!lazy[x]) return ; mark(x<<1,lazy[x]); mark(x<<1|1,lazy[x]); lazy[x]=0; } void build(int l,int r,int x) { if(l==r) { tree[x].set(a[idx[l]]); return ; } int mid=(l+r)>>1; build(l,mid,x<<1); build(mid+1,r,x<<1|1); push(x); } void update(int pos,int l,int r,int x,int y,int k) { if(x<=l && r<=y) { mark(pos,k); return; } int mid=(l+r)>>1; pushdown(l,r,pos); if(x<=mid) update(pos<<1,l,mid,x,y,k); if(y>mid) update(pos<<1|1,mid+1,r,x,y,k); push(pos); } bitset<64> ask(int pos,int l,int r,int x,int y) { if(x<=l && r<=y) return tree[pos]; pushdown(l,r,pos); int mid=(l+r)>>1; bitset<64> bb; if(x<=mid) bb|=ask(pos<<1,l,mid,x,y); if(y>mid) bb|=ask(pos<<1|1,mid+1,r,x,y); return bb; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<n;i++) { int x=read(),y=read(); e[x].push_back(y); e[y].push_back(x); } dfs1(1,0); build(1,n,1); while(m--) { int op=read(); if(op==1) { int x=read(),y=read(); update(1,1,n,id[x],id[x]+siz[x]-1,y); } else { int x=read(); printf("%d\n",ask(1,1,n,id[x],id[x]+siz[x]-1).count()); } } return 0; }
小总
感觉下午讲的前两题和后两题还不难,中间忽然出现一个神秘题,题目大部分是CF上的,平均3000+
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】