T1 Merchant


如果$t=0$时不能达到$s$,那么所拿物品的价值一定关于时间单调递增,答案单调。因此可以特判$0$后二分。

用$sort$复杂度被卡,要用$\textit{nth_element}$,相当于$sort$只递归一边,均摊$O(n)$。

$check$时遇到小于零的直接跳过,达到$s$后直接$return$,不然可能爆$\textit{long long}$。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 #define rin register signed
4 using namespace std;
5 const int NN=1e6+5;
6 int n,m,s,spj,ans,l,r=1e9,mid,tmp[NN];
7 struct line{ int k,b; }ln[NN];
8 inline bool cmp(line a,line c){ return a.b>c.b;}
9 inline bool cmpn(int a,int b){ return a>b; }
10 inline int read(){
11 int x=0,f=1; char ch=getchar();
12 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
13 while(ch<='9'&&ch>='0'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
14 return x*f;
15 }
16 inline void write(int x){
17 char ch[20]; int len=0;
18 if(x<0) x=~x+1, putchar('-');
19 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
20 for(rin i=len-1;i>=0;--i) putchar(ch[i]);
21 }
22 inline bool check(int mid){
23 int res=0;
24 for(int i=1;i<=n;i++) tmp[i]=ln[i].k*mid+ln[i].b;
25 nth_element(tmp+1,tmp+m+1,tmp+n+1,cmpn);
26 for(int i=1;i<=m;i++){
27 if(tmp[i]<=0) continue;
28 res+=tmp[i];
29 if(res>=s) return 1;
30 }
31 return 0;
32 }
33 signed main(){
34 n=read(); m=read(); s=read();
35 for(rin i=1;i<=n;i++)
36 ln[i].k=read(), ln[i].b=read();
37 sort(ln+1,ln+n+1,cmp);
38 for(int i=1;i<=m;i++){
39 spj+=ln[i].b;
40 if(spj>=s){ puts("0"); return 0; }
41 }
42 while(l<=r){
43 mid=l+r>>1;
44 if(check(mid)) ans=mid, r=mid-1;
45 else l=mid+1;
46 }
47 write(ans); putchar('\n');
48 return 0;
49 }

T1

T2 Equation


可以在$DFS$中求出当前点u与一号节点形成的式子,同时可以通过该点深度得到与一号节点形成的式子是加是减。然后简单消元可以得到想要的方程,直接求解判断即可。

修改时要修改子树中所有节点,在$DFS$序上建两个差分树状数组,一个记加法节点,一个记减法节点,修改时操作相反。

其实一个树状数组也行,用时取负即可。

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 const int NN=1e6+5;
5 int n,q,to[NN<<1],nex[NN<<1],head[NN],num,w[NN],op,u,v,ww;
6 int typ[NN],dep[NN],siz[NN],dfn[NN],cnt;
7 struct tr{
8 int c[NN];
9 int lowbit(int x){ return x&(-x); }
10 void insert(int val,int pos){
11 while(pos<=n){
12 c[pos]+=val;
13 pos+=lowbit(pos);
14 }
15 }
16 int query(int pos){
17 int res=0;
18 while(pos){
19 res+=c[pos];
20 pos-=lowbit(pos);
21 }
22 return res;
23 }
24 }c[2];
25 inline int read(){
26 int x=0,f=1; char ch=getchar();
27 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
28 while(ch<='9'&&ch>='0'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
29 return x*f;
30 }
31 inline void write(int x){
32 char ch[20]; int len=0;
33 if(x<0) x=~x+1, putchar('-');
34 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
35 for(int i=len-1;i>=0;--i) putchar(ch[i]);
36 }
37 inline void add(int a,int b){
38 to[++num]=b; nex[num]=head[a]; head[a]=num;
39 to[++num]=a; nex[num]=head[b]; head[b]=num;
40 }
41 void dfs(int f,int s,int pre){
42 dep[s]=dep[f]+1; siz[s]=1; dfn[s]=++cnt;
43 typ[s]=(dep[s]&1)?0:1;
44 c[typ[s]].insert(pre,dfn[s]);
45 c[typ[s]].insert(-pre,dfn[s]+1);
46 for(int i=head[s];i;i=nex[i]){
47 int v=to[i];
48 if(v==f) continue;
49 dfs(s,v,w[v]-pre);
50 siz[s]+=siz[v];
51 }
52 }
53 void calc(int u,int v,int ww){
54 int tu=typ[u],tv=typ[v],uu;
55 int wu=c[tu].query(dfn[u]);//-c[tu].query(dfn[u]-1);
56 int wv=c[tv].query(dfn[v]);//-c[tv].query(dfn[v]-1);
57 if(tu^tv){ puts((wu+wv)==ww?"inf":"none"); return; }
58 if((ww+wu-wv)&1){ puts("none"); return; }
59 uu=(ww+wu-wv)>>1;
60 write(tu?(wu-uu):(uu-wu)); putchar('\n');
61 }
62 signed main(){
63 n=read(); q=read();
64 for(int i=2;i<=n;i++){
65 int tmp=read(); add(i,tmp);
66 w[i]=read();
67 } dfs(0,1,0);
68 while(q--){
69 op=read();
70 if(op==1) u=read(), v=read(), ww=read(), calc(u,v,ww);
71 else{
72 u=read(); int tmp=w[u]; w[u]=read();
73 c[typ[u]].insert(w[u]-tmp,dfn[u]);
74 c[typ[u]].insert(tmp-w[u],dfn[u]+siz[u]);
75 c[typ[u]^1].insert(tmp-w[u],dfn[u]);
76 c[typ[u]^1].insert(w[u]-tmp,dfn[u]+siz[u]);
77 }
78 }
79 return 0;
80 }

T2

T3 Rectangle


好像能扫描线做?但不会。

首先考虑坐标不重的情况。枚举矩形右边界$i$,再向左枚举左边界$j$,然后考虑左右边界中的点。

记矩形至少的上界为$y_x$,至多的下界为$y_n$,那么这四个边界对答案的贡献:

$(i-j)\times \sum_{p<y_n} \sum_{q>y_x}(y_x-y_n)$

记录大于$y_x$和小于$y_n$的点的个数与总和,两两相乘再相减即可。

考虑可重的情况。这时因为左右边界有很多点,同一矩形就可能被重复计算。利用这些点把大矩形分为若干个小矩形分别计算即可。

友校大佬简洁易懂的讲解

$code:$

 1 #include<bits/stdc++.h>
2 #define int long long
3 #define pb push_back
4 using namespace std;
5 const int NN=1e4+5,p=1e9+7;
6 int n,ans;
7 bool vis[2501][2501];
8 vector<int>sub[2501];
9 inline int read(){
10 int x=0,f=1; char ch=getchar();
11 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); }
12 while(ch<='9'&&ch>='0'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
13 return x*f;
14 }
15 inline void write(int x){
16 char ch[20]; int len=0;
17 if(x<0) x=~x+1, putchar('-');
18 do{ ch[len++]=x%10+(1<<5)+(1<<4); x/=10; }while(x);
19 for(int i=len-1;i>=0;--i) putchar(ch[i]);
20 }
21 struct trearray{
22 int c[2501][2];
23 void insert(int k,int x,int pos){
24 while(pos<=2500){
25 c[pos][k]+=x;
26 pos+=(pos&(-pos));
27 }
28 }
29 int query(int k,int pos){
30 int res=0;
31 while(pos){
32 res+=c[pos][k];
33 pos-=(pos&(-pos));
34 }
35 return res;
36 }
37 }t[2501];
38 signed main(){
39 n=read();
40 for(int i=1;i<=n;i++){
41 int x=read(),y=read();
42 sub[x].pb(y);
43 }
44 for(int i=1;i<=2500;i++){
45 sort(sub[i].begin(),sub[i].end());
46 sub[i].pb(2501);
47 }
48 for(int i=1;i<=2500;i++){
49 if(sub[i].size()==1) continue;
50 for(int j=0;j<sub[i].size()-1;j++) if(!vis[i][sub[i][j]]){
51 vis[i][sub[i][j]]=1;
52 t[i].insert(0,sub[i][j],sub[i][j]);
53 t[i].insert(1,1,sub[i][j]);
54 }
55 for(int j=i-1;j;j--){
56 if(sub[j].size()==1) continue;
57 for(int k=0;k<sub[j].size()-1;k++) if(!vis[i][sub[j][k]]){
58 vis[i][sub[j][k]]=1;
59 t[i].insert(0,sub[j][k],sub[j][k]);
60 t[i].insert(1,1,sub[j][k]);
61 }
62 int lmt=max(sub[i][0],sub[j][0]),tmp1=0,tmp2=0,flag;
63 while(sub[i][tmp1+1]<=lmt) tmp1++;
64 while(sub[j][tmp2+1]<=lmt) tmp2++;
65 while(tmp1<sub[i].size()-1&&tmp2<sub[j].size()-1){
66 flag=min(sub[i][tmp1+1],sub[j][tmp2+1]);
67 (ans+=(i-j)*(t[i].query(0,flag-1)-t[i].query(0,lmt-1))*t[i].query(1,min(sub[i][tmp1],sub[j][tmp2])))%=p;
68 (ans-=(i-j)*(t[i].query(1,flag-1)-t[i].query(1,lmt-1))*t[i].query(0,min(sub[i][tmp1],sub[j][tmp2])))%=p;
69 (ans+=p)%=p;
70 lmt=flag;
71 if(sub[i][tmp1+1]<=lmt) tmp1++;
72 if(sub[j][tmp2+1]<=lmt) tmp2++;
73 }
74 }
75 }
76 write(ans); putchar('\n');
77 return 0;
78 }

T3

2021.8.9考试总结[NOIP模拟34]的更多相关文章

  1. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  2. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  3. 2021.8.11考试总结[NOIP模拟36]

    T1 Dove玩扑克 考场并查集加树状数组加桶期望$65pts$实际$80pts$,考后多开个数组记哪些数出现过,只扫出现过的数就切了.用$set$维护可以把被删没的数去掉,更快. $code:$ 1 ...

  4. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  5. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  6. 2021.10.10考试总结[NOIP模拟73]

    T1 小L的疑惑 对于\(P_i\),如果所有比\(P_i\)小的数加起来也达不到\(P_i-1\),那么值域肯定不连续.否则设原来值域最大值为\(mx\),则\(P_i\)会让值域最大值增致\(mx ...

  7. 2021.9.20考试总结[NOIP模拟57]

    (换个编辑器代码就SB地不自动折叠了.. T1 2A 考察快读的写法. $code:$ T1 #include<bits/stdc++.h> #define scanf SCANF=sca ...

  8. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  9. 2021.9.12考试总结[NOIP模拟51]

    T1 茅山道术 仔细观察发现对于每个点只考虑它前面第一个与它颜色相同的点即可. 又仔细观察发现对一段区间染色后以这个区间内点为端点的区间不能染色. 于是对区间右端点而言,区间染色的贡献为遍历到区间左端 ...

随机推荐

  1. SpringBoot异步使用@Async原理及线程池配置

    前言 在实际项目开发中很多业务场景需要使用异步去完成,比如消息通知,日志记录,等非常常用的都可以通过异步去执行,提高效率,那么在Spring框架中应该如何去使用异步呢 使用步骤 完成异步操作一般有两种 ...

  2. 加入Erlang社区-指引

    国内暂且没有发现较活跃.人气较高的论坛或者社区,偶然发现Erlang官网的Community页面描述了一个Slack交流平台,里面有众多异国他乡的大佬,感兴趣的.有技术疑问的都可以加入看看. 加入教程 ...

  3. Android学习记录(一)——安装Android Studio

    "工欲善其事必先利其器"学习安卓开发的第一步,安装Android Studio. 一.什么是Android Studio? Android Studio 是谷歌推出的一个Andro ...

  4. SpringBoot 如何进行对象复制,老鸟们都这么玩的!

    大家好,我是飘渺. 今天带来SpringBoot老鸟系列的第四篇,来聊聊在日常开发中如何优雅的实现对象复制. 首先我们看看为什么需要对象复制? 为什么需要对象复制 如上,是我们平时开发中最常见的三层M ...

  5. Kotlin协程基础

    开发环境 IntelliJ IDEA 2021.2.2 (Community Edition) Kotlin: 212-1.5.10-release-IJ5284.40 我们已经通过第一个例子学会了启 ...

  6. mac php安装扩展 如 seoole apcu

    //下载 --安装 --复制扩展文件到对应目录 wget https://pecl.php.net/get/apcu-5.1.7.tgz tar -zvcf pcu-5.1.7.tgz cd 到解压目 ...

  7. mybatis多条件多值批量更新

    mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现. 这里使用了case when 这个小技巧来实现批量更新. 举个例子: UPDATE 表名 SET    display_ord ...

  8. c++ 的学习笔记 第一集cim cout

    1. 你要用这个东西,所以得有包含它得头文件,就像java 你要用某个模块,你得包含这个模块 模块化??单片机里面学的模块化(可以在vs里面实现) 2. 当我把注册表regedit 程序删除之后成功了 ...

  9. P5445-[APIO2019]路灯【set,树状数组套线段树】

    正题 题目链接:https://www.luogu.com.cn/problem/P5445 题目大意 \(n+1\)个点,\(i\)和\(i+1\)个点之间有一条边,\(q\)个操作 断开/连接第\ ...

  10. ASP.NET Core 学习笔记 第二篇 依赖注入

    前言 ASP.NET Core 应用在启动过程中会依赖各种组件提供服务,而这些组件会以接口的形式标准化,这些组件这就是我们所说的服务,ASP.NET Core框架建立在一个底层的依赖注入框架之上,它使 ...