这次考试还算可以(吧),暴力都没打满,但是还差很多。

T1 强烈推荐我的打法,很好理解并且很好打(虽然稍长)

维护指针指向的值及其是第几个数,然后分类讨论。

(诡异构造的序列==随机数据)??

 #include<cstdio>
#include<iostream>
using namespace std;
const int N=1e8+7e7+9e6+4e5+2e4+5e3;
char v[N+];
int s[+],tot,prime[+];
void pre()
{
for(register int i=;i<=N;i++)
{
if(!v[i]) prime[++tot]=i;
for(register int j=;j<=tot&&prime[j]*i<=N;j++)
{
v[i*prime[j]]=;
if(i%prime[j]==) break;
}
}
return ;
}
int c[];//维护指向的值,以及该值的第几个数
struct node{
int val,num;
inline void moveleft()
{
if(num>) {num--;return ;}
num=;val--;
while(!c[val]) val--;
num=c[val];
}
inline void moveright()
{
if(num<c[val]){num++;return ;}
val++;
while(!c[val]) val++;
num=;
}
inline void del(int x)
{
if(x==val)
{
if(c[x]<num) moveright();
return ;
}
if(x<val) moveright();
}
inline void add(int x)
{
if(x<val) moveleft();
}
}tl,tr;
int main()
{
pre();
int n,k,w;double ans=;
scanf("%d%d%d",&n,&k,&w);
for(register int i=;i<=n;i++) s[i]=(1ll*prime[i]*i)%w;
for(register int i=n;i>=;i--) s[i]=s[i]+s[i/+];
for(register int i=;i<=k;i++) c[s[i]]++;
if(k&)
{
int tmp=;
for(register int i=;i<=w*;i++)
{
if(tmp+c[i]>=k/+)
{
tl.val=i;
tl.num=k/+-tmp;
break;
}
tmp+=c[i];
}
for(register int i=;i<=n-k+;i++)
{
ans+=tl.val;
--c[s[i]],tl.del(s[i]);
if(i+k<=n) ++c[s[i+k]],tl.add(s[i+k]);
}
}
else
{
int tmp=;
for(register int i=;i<=w*;i++)
{
if(!tl.num&&tmp+c[i]>=k/)
tl.val=i,tl.num=k/-tmp;
if(tmp+c[i]>=k/+)
{
tr.val=i;
tr.num=k/+-tmp;
break;
}
tmp+=c[i];
}
for(register int i=;i<=n-k+;i++)
{
ans+=1.0*(tl.val+tr.val)/;
--c[s[i]];
tl.del(s[i]);tr.del(s[i]);
if(i+k<=n) ++c[s[i+k]],tl.add(s[i+k]),tr.add(s[i+k]);
}
}
printf("%.1lf",ans);
}

T2 也是维护指针,维护一个大小为n的序列,每次删掉$MAX$,然后插入一个,由于每次插入的如果比$MAX$大的话是板逼要被直接删掉的,

所以指针单调不增,复杂度$O(nk)$

 #include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
int a[],cnt[];
int b[];
int main()
{
int n,k,p,tot;
scanf("%d%d",&n,&k);
for(register int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];tot=n;
sort(b+,b+n+);tot=unique(b+,b+n+)-b-;
for(register int i=;i<=n;i++) a[i]=lower_bound(b+,b+tot+,a[i])-b;
while(k--)
{
scanf("%d",&p);int tmp=;long long ans=;
for(register int i=;i<=p;tmp=max(tmp,a[i]),++cnt[a[i]],i++);
register int i=p+,cur=;
for(register int j=;j<=n;j++)
{
if(cur&) ans+=b[tmp];
else ans-=b[tmp];
cur^=;cnt[tmp]--;
while(tmp&&!cnt[tmp]) tmp--;
while(i<=n&&a[i]>tmp)
{
if(cur&) ans+=b[a[i]];
else ans-=b[a[i]];
j++;i++;cur^=;
}
if(i<=n) cnt[a[i++]]++;
}
printf("%lld\n",ans);
}
return ;
}

T3 树形DP,大样例一定要$freopen$,就因为这个我以为大样例没过调了一个多小时。

假设$dp[i][j][0/1]$表示到i点撒了j块面包到子树/子树到i点的最大值,直接维护然后合并。

 /*
子树到i 直接转移即可 合并的时候i撒的贡献要减少p[y]
i到子树 直接转移即可
kx变成sb了 呜呜呜呜呜呜
#include<iostream>
using namespace std;
int main(){int a,b;cin>>a>>b;cout<<a+b<<endl;return 0;}
*/
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n,t,head[],to[*],nxt[*],cnt,p[];
LL s[],f[][][],mx[][],ans;//0 子树到i (只考虑向下) 1 i到子树
inline void Add(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
void dp(int x,int fa)
{
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(y==fa) continue;
dp(y,x);
}
memset(mx,,sizeof mx);
for(int i=head[x];i;i=nxt[i])
{
if(to[i]==fa) continue;
int y=to[i];
for(register int j=;j<=t;j++)
{
ans=max(ans,max(mx[t-j][]+f[y][j][],mx[t-j][]+f[y][j][]));
if(j^t) ans=max(ans,mx[t-j-][]+f[y][j][]+s[x]);
if(j) ans=max(ans,f[y][j-][]-p[y]+mx[t-j][]+s[x]);
}
for(register int j=;j<=t;j++)
{
mx[j][]=max(mx[j][],f[y][j][]);
mx[j][]=max(mx[j][],f[y][j][]);
mx[j][]=max(mx[j][],f[y][j][]-p[y]);
}
}
f[x][][]=s[x],f[x][][]=s[x]-p[fa];
for(register int i=head[x];i;i=nxt[i])
{
if(to[i]==fa) continue;
int y=to[i];
for(register int j=;j<=t;j++)
f[x][j][]=max(f[x][j][],max(f[y][j][],f[y][j-][]+s[x]-p[y])),
f[x][j][]=max(f[x][j][],max(f[y][j][],f[y][j-][]+s[x]-p[fa]));
}
}
signed main()
{
srand((unsigned)time());
scanf("%d%d",&n,&t);
for(register int i=;i<=n;i++) scanf("%d",&p[i]);
for(register int i=,a,b;i<n;i++) scanf("%d%d",&a,&b),Add(a,b),Add(b,a),s[a]+=p[b],s[b]+=p[a];
dp(,);
printf("%lld\n",ans);
return ;
}

csps63总结的更多相关文章

随机推荐

  1. 【Java】获取当前操作系统桌面路径

    //当前用户桌面 File desktopDir = FileSystemView.getFileSystemView() .getHomeDirectory(); String desktopPat ...

  2. python语言程序设计基础(嵩天)第三章课后习题部分个人练习

    p69: *题3.5: 源代码: (1)print(30-3**2+8//3**2*10)     答案:21 (2)print(3*4**2/8%5)     答案:1.0 (3)print(2** ...

  3. Label的作用是什么,是怎么用的?

    label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到标签相关的表单控件上. 如: <form> <label for="male"&g ...

  4. 什么是STM32的ISP?

    上一篇笔记分享了STM32的串口IAP实例:STM32串口IAP分享.其中,下载IAP程序时用ISP的方式进行下载.这里的ISP又是什么呢? ISP方式下载程序原理 ISP:In System Pro ...

  5. 常见PHP危险函数及特殊函数

    PHP代码执行函数 - eval & assert & preg_replace mixed eval ( string $code ) 把字符串 $code 作为PHP代码执行. 很 ...

  6. ssh隧道代理连接

    0x00 什么是SSH隧道 场景: 假设有两台主机: A主机为外网,B主机为内网通常来说外网主机A是无法直接连接到内网主机B的,这时如果要实现A主机通过ssh控制B主机,通常来说有两种方法: 1.端口 ...

  7. vue在一个方法执行完后再执行另一个方法

    vue在一个方法执行完后执行另一个方法 用Promise来实现.Promise是ES6的新特性,用于处理异步操作逻辑,用过给Promise添加then和catch函数,处理成功和失败的情况 ES7中新 ...

  8. Python开发【第一篇】:目录

    本系列博文包含Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习Python编程的朋友们提供一点帮助! .Python开发[第一篇]:目录 .Python开发[第二篇]:初始P ...

  9. python编程系列---tcp服务端的简单实现

    流程如下: """tcp服务端创建流程1. 创建服务端的tcp socket : server_socket 用于监听客户端的请求2. 绑定端口3. server_soc ...

  10. 小白终于弄懂了:c#从async/await到Task再到Thread

    1. 为什么会有/怎么解决: async/await的无限嵌套 public async Task<int> myFuncAsync1() { //some code int num = ...