用心出题,用脚造数据

乱搞场

 1 #include<bits/stdc++.h>
2 #define re register
3 #define int long long
4 #define inf 0x7ffffffffffffff
5 using namespace std;
6 int n,a[100010],b[100010],ans=inf;
7 double st,ed;
8 inline int read(){
9 re int a=0,b=1; re char ch=getchar();
10 while(ch<'0'||ch>'9')
11 b=(ch=='-')?-1:1,ch=getchar();
12 while(ch>='0'&&ch<='9')
13 a=(a<<3)+(a<<1)+(ch^48),ch=getchar();
14 return a*b;
15 }
16 inline int max(re int x,re int y){if(x>y) return x; return y;}
17 inline int min(re int x,re int y){if(x<y) return x; return y;}
18 inline void dfs(re int x,re int l,re int r,re int ll,re int rr){
19 if(1ll*(r-l)*(rr-ll)>ans) return ;
20 if(x>n){
21 ans=1ll*(r-l)*(rr-ll);
22 ed=clock();
23 if((ed-st)/1e6>=1.99){
24 printf("%lld\n",ans);
25 exit(0);
26 }
27 return ;
28 }
29 dfs(x+1,max(l,a[x]),min(r,a[x]),max(ll,b[x]),min(rr,b[x]));
30 dfs(x+1,max(l,b[x]),min(r,b[x]),max(ll,a[x]),min(rr,a[x]));
31 }
32 signed main(){
33 // freopen("in.txt","r",stdin);
34 n=read();if(n==1){puts("1");return 0;}
35 for(re int i=1;i<=n;++i){
36 a[i]=read(),b[i]=read();
37 if(a[i]<b[i]) a[i]^=b[i]^=a[i]^=b[i];
38 }
39 st=clock();
40 dfs(1,0,inf,0,inf);
41 printf("%lld\n",ans);
42 return 0;
43 }

随机化

 1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #include<bits/stdc++.h>
6 #define reg register
7 using namespace std;
8 typedef long long ll;
9 const int maxn=1e5+5,INF=2e9;
10 inline void read(int &x)
11 {
12 x=0;char c=getchar();
13 while(c<'0'||c>'9') c=getchar();
14 while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-48,c=getchar();
15 }
16 ll ans;
17 int S,T,n,tot,L[maxn][2],R[maxn][2],L2[2],R2[2],tmp[2],yet[maxn];
18 struct ball{
19 int x[2];
20 }c[maxn];
21 struct wh{
22 int x,id,f;
23 bool friend operator < (const wh a,const wh b) {return a.x<b.x;}
24 }g[maxn<<1];
25 void dfs(int x)
26 {
27 T=clock();
28 if(T-S>1500000) {printf("%lld\n",ans);exit(0);}
29 if(x!=1&&1LL*(L[x-1][1]-L[x-1][0])*(R[x-1][1]-R[x-1][0])>ans) return ;
30 if(x==n+1) {ans=1LL*(L[x-1][1]-L[x-1][0])*(R[x-1][1]-R[x-1][0]);return ;}
31 if(c[x].x[0]>c[x].x[1]) swap(c[x].x[0],c[x].x[1]);
32 for(reg int j=0;j<=1;++j)
33 {
34 L[x][0]=min(L[x-1][0],c[x].x[j]);
35 L[x][1]=max(L[x-1][1],c[x].x[j]);
36 R[x][0]=min(R[x-1][0],c[x].x[j^1]);
37 R[x][1]=max(R[x-1][1],c[x].x[j^1]);
38 dfs(x+1);
39 }
40 }
41 int main()
42 {
43 srand(time(NULL));
44 S=clock();
45 // freopen("ans.in","r",stdin);
46 // freopen("b.out","w",stdout);
47 read(n);
48 for(reg int i=1;i<=n;++i)
49 {
50 read(c[i].x[0]),read(c[i].x[1]);
51 g[++tot]=(wh){c[i].x[0],i,0};
52 g[++tot]=(wh){c[i].x[1],i,1};
53 }
54 reverse(c+1,c+n+1);
55 sort(g+1,g+tot+1);
56 ans=1e18;ans+=5;
57 int l=1,r=tot,k=0;
58 memset(yet,0xFF,sizeof(yet));
59 while(k<n)
60 {
61 while(yet[g[l].id]!=-1) ++l;
62 yet[g[l].id]=g[l].f;++k;
63 if(k==n) break;
64 while(yet[g[r].id]!=-1) --r;
65 yet[g[r].id]=g[r].f;++k;
66 }
67 L[0][0]=R[0][0]=L2[0]=R2[0]=INF;
68 for(reg int i=1;i<=n;++i)
69 {
70 L2[0]=min(L2[0],c[i].x[yet[i]]);
71 L2[1]=max(L2[1],c[i].x[yet[i]]);
72 R2[0]=min(R2[0],c[i].x[yet[i]^1]);
73 R2[1]=max(R2[1],c[i].x[yet[i]^1]);
74 }
75 ans=1LL*(L2[1]-L2[0])*(R2[1]-R2[0]);
76 dfs(1);
77 printf("%lld\n",ans);
78 return 0;
79 }

clock

垃圾zzn当然什么也不会啦,乱搞什么也没打

D

考试时想到正解,没打,觉得这仅仅是个简单的剪枝,没想到啊

题意

求$(r-l+1)*gcd(a[l],a[l+1],.....,a[r])$最大值

题解

垃圾zzn没打正解,类正解多$log$用来二分了,常数较小

$gcd$总需要求,求次数太多了

考虑二分,维护$gcd$从$mid$前缀和后缀和

这样你就有$50$分了

考虑$gcd$变化次数小于是维护单调队列,很简单

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 #define A 333333
5 ll a[A],suml[A],sumr[A],dll[A],dlr[A];
6 ll ans=0,n;
7 ll gcd(ll x,ll y){
8 if(y==0) return x;
9 return gcd(y,x%y);
10 }
11 void solve(ll l,ll r){
12 if(l==r) return ;
13 ll mid=(l+r)>>1,rnow=mid+1,lnow=mid;
14 suml[lnow]=a[lnow],sumr[rnow]=a[rnow];
15 dll[0]=0,dlr[0]=0;
16 while(lnow>l){
17 lnow--;
18 suml[lnow]=gcd(suml[lnow+1],a[lnow]);
19 if(suml[lnow]!=suml[lnow+1])
20 dll[++dll[0]]=lnow+1;
21 }
22 dll[++dll[0]]=l;
23 while(rnow<r){
24 rnow++;
25 sumr[rnow]=gcd(sumr[rnow-1],a[rnow]);
26 if(sumr[rnow]!=sumr[rnow-1])
27 dlr[++dlr[0]]=rnow-1;
28 }
29 dlr[++dlr[0]]=r;
30 for(ll lh=1;lh<=dll[0];lh++)
31 for(ll rh=1;rh<=dlr[0];rh++){
32 ll nowl=dll[lh],nowr=dlr[rh];
33 ll g=gcd(suml[nowl],sumr[nowr]);
34 // printf("nowl=%lld nowr=%lld =%lld\n",dll[lh],dlr[rh],g*(nowr-nowl+1));
35 if(g==1) break;
36 ans=max(ans,g*(nowr-nowl+1));
37 }
38 ans=max(ans,gcd(suml[l],sumr[r])*(r-l+1));
39 solve(l,mid);solve(mid+1,r);
40 }
41 //10 10 101 10 10
42 int main(){
43 // freopen("da.in","r",stdin);
44 // freopen("ans.sol","w",stdout);
45 scanf("%lld",&n);
46 for(ll i=1;i<=n;i++){
47 scanf("%lld",&a[i]);
48 }
49 solve(1,n);
50 printf("%lld\n",ans);
51 }

E

这个题真的很迷

题解

垃圾zzn考试时打的第二个贪心,然后只有$60$分,事实上单纯第一个贪心就可以$100$分,数据特别水,第一个贪心明明连样例都过不去

没遇到数据这么水的,

正确性垃圾zzn当然不会验证啦

代码也懒的放了

F

题解

0分算法

直接暴力$dp$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 ll f[2][2019][2019],w[2019];
5 ll a,b,n,q;
6 int main(){
7 scanf("%lld%lld%lld%lld",&n,&q,&a,&b);
8 memset(f,0x7f,sizeof(f));
9 for(ll i=1;i<=q;i++)
10 scanf("%lld",&w[i]);
11 f[1][a][w[1]]=abs(b-w[1]);
12 f[1][w[1]][b]=abs(a-w[1]);
13 for(ll i=2;i<=q;i++){
14 memset(f[i&1],0x7f,sizeof(f[i&1]));
15 for(ll j=1;j<=n;j++){
16 f[i&1][j][w[i]]=min(f[i&1][j][w[i]],f[(i-1)&1][j][w[i-1]]+abs(w[i]-w[i-1]));//w[i-1]移动到w[i]
17 f[i&1][w[i]][w[i-1]]=min(f[i&1][w[i]][w[i-1]],f[(i-1)&1][j][w[i-1]]+abs(j-w[i]));//j移动到w[i]
18 f[i&1][w[i]][j]=min(f[i&1][w[i]][j],f[(i-1)&1][w[i-1]][j]+abs(w[i]-w[i-1]));//w[i-1]移动到w[i]
19 f[i&1][w[i-1]][w[i]]=min(f[i&1][w[i-1]][w[i]],f[(i-1)&1][w[i-1]][j]+abs(j-w[i]));//j移动到w[i]
20 }
21 }
22 ll ans=0x7fffffff;
23 for(ll j=1;j<=n;j++){
24 ans=min(ans,min(f[q&1][j][w[q]],f[q&1][w[q]][j]));
25 }
26 printf("%lld\n",ans);
27 }

30分算法

有一维一定是$w[i]$

考虑去掉一维

$f[i][j]=f[i-1][j]+abs(w[i]-w[i-1])$另一个指针从$w[i-1]$移动到$w[i]$

$f[i][w[i-1]]=f[i-1][j]+abs(j-w[i])$从$j$移动到$w[i]$

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll f[2][2019],w[2019];
ll a,b,n,q;
int main(){
scanf("%lld%lld%lld%lld",&n,&q,&a,&b);
memset(f,0x7f,sizeof(f));
for(ll i=1;i<=q;i++)
scanf("%lld",&w[i]);
f[1][a]=abs(b-w[1]);
f[1][b]=abs(a-w[1]);
for(ll i=2;i<=q;i++){
memset(f[i&1],0x7f,sizeof(f[i&1]));
for(ll j=1;j<=n;j++){
f[i&1][j]=min(f[i&1][j],f[(i-1)&1][j]+abs(w[i]-w[i-1]));
f[i&1][w[i-1]]=min(f[i&1][w[i-1]],f[(i-1)&1][j]+abs(j-w[i]));
f[i&1][j]=min(f[i&1][j],f[(i-1)&1][j]+abs(w[i]-w[i-1]));
f[i&1][w[i-1]]=min(f[i&1][w[i-1]],f[(i-1)&1][j]+abs(j-w[i]));
}
}
ll ans=0x7fffffff;
for(ll j=1;j<=n;j++){
ans=min(ans,min(f[q&1][j],f[q&1][j]));
}
printf("%lld\n",ans);
}

100分算法

两个转移式子

$f[i][j]=f[i-1][j]+abs(w[i]-w[i-1])$

$f[i][w[i-1]]=f[i-1][j]+abs(j-w[i])$

发现第一个式子就是区间加,第二个式子单点赋值

单点赋值赋的就是$min$,有个$abs$怎么办维护$f-j$最小值和$f+j$最小值

        memset(askmin,0x7f,sizeof(askmin));
seg_min(1,1,w[i],2);//p[i]比当前点大,那么取p[i]-l
seg_min(1,w[i],n,1);//p[i]比当前值小,取l-p[i]
// printf("ask=%lld %lld\n",askmin[1],askmin[2]);
askmin[1]-=w[i];
askmin[2]+=w[i];
ll nowmin=min(askmin[1],askmin[2]);

线段树优化一下

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define ll long long
4 ll w[1010101],askmin[4];
5 ll a,b,n,q;
6 struct tree{
7 ll l,r,f,minn[4];
8 }tr[1010101];
9 void up(ll x){
10 for(ll i=1;i<=3;i++)
11 tr[x].minn[i]=min(tr[x<<1].minn[i],tr[x<<1|1].minn[i]);
12 }
13 void down(ll x){
14 tr[x<<1].f+=tr[x].f;
15 tr[x<<1|1].f+=tr[x].f;
16 for(ll i=1;i<=3;i++)
17 tr[x<<1].minn[i]+=tr[x].f,tr[x<<1|1].minn[i]+=tr[x].f;
18 tr[x].f=0;
19 }
20 void built(ll x,ll l,ll r){//printf("builx=%lld\n",x);
21 tr[x].l=l,tr[x].r=r;
22 if(l==r){
23 if(l==a||l==b){
24 tr[x].minn[3]=abs(a+b-l-w[1]);
25 // printf("tr3=%lld\n",tr[x].minn[3]);
26 tr[x].minn[1]=tr[x].minn[3]+l;
27 tr[x].minn[2]=tr[x].minn[3]-l;
28 }
29 else tr[x].minn[1]=tr[x].minn[2]=tr[x].minn[3]=0x7ffffffffff;
30 return ;
31 }
32 ll mid=(l+r)>>1;
33 built(x<<1,l,mid);
34 built(x<<1|1,mid+1,r);
35 up(x);
36 }
37 void seg_min(ll x,ll l,ll r,ll zl){
38 // printf("l=%lld r=%lld\n",l,r);
39 if(tr[x].l>=l&&tr[x].r<=r){
40 // printf("tr[%lld].minn[%lld]=%lld l=%lld r=%lld\n",x,zl,tr[x].minn[zl],tr[x].l,tr[x].r);
41 askmin[zl]=min(askmin[zl],tr[x].minn[zl]);
42 return ;
43 }
44 down(x);
45 ll mid=(tr[x].l+tr[x].r)>>1;
46 if(mid>=l) seg_min(x<<1,l,r,zl);
47 if(mid<r) seg_min(x<<1|1,l,r,zl);
48 up(x);
49 }
50 void add(ll x,ll point,ll val){
51 if(tr[x].l==tr[x].r){
52 tr[x].minn[3]=min(tr[x].minn[3],val);
53 tr[x].minn[1]=tr[x].minn[3]+tr[x].l;
54 tr[x].minn[2]=tr[x].minn[3]-tr[x].l;
55 return ;
56 }
57 down(x);
58 ll mid=(tr[x].l+tr[x].r)>>1;
59 if(point<=mid) add(x<<1,point,val);
60 else add(x<<1|1,point,val);
61 up(x);
62 }
63 int main(){
64 scanf("%lld%lld%lld%lld",&n,&q,&a,&b);
65 for(ll i=1;i<=q;i++)
66 scanf("%lld",&w[i]);
67 built(1,1,n);
68 for(ll i=2;i<=q;i++){
69 memset(askmin,0x7f,sizeof(askmin));
70 seg_min(1,1,w[i],2);//p[i]比当前点大,那么取p[i]-l
71 seg_min(1,w[i],n,1);//p[i]比当前值小,取l-p[i]
72 // printf("ask=%lld %lld\n",askmin[1],askmin[2]);
73 askmin[1]-=w[i];
74 askmin[2]+=w[i];
75 ll nowmin=min(askmin[1],askmin[2]);
76 // printf("nowmin=%lld\n",nowmin);
77 tr[1].f+=abs(w[i]-w[i-1]);
78 for(ll j=1;j<=3;j++)
79 tr[1].minn[j]+=abs(w[i]-w[i-1]);
80 add(1,w[i-1],nowmin);
81 }
82 printf("%lld\n",tr[1].minn[3]);
83 }

最新文章

  1. Python模拟实现Linux系统unix2dos功能
  2. UVA136 求第1500个丑数
  3. bootstrap-12
  4. HDU 4349 Xiao Ming&#39;s Hope lucas定理
  5. Spring MVC常用的注解类
  6. 7 天玩转 ASP.NET MVC - 第 1 天
  7. Frame Stacking 框架堆叠
  8. GitHub使用教程for Eclipse
  9. hdu_1875_畅通工程再续 prim和kruskal
  10. Sping3.0版本+Quartz完成定时任务
  11. unity 创建NGUI字体
  12. git链接GitHub命令及基本操作
  13. 简单的CSS颜色查看工具
  14. Treasure of the Chimp Island
  15. 【CSS3】动画animation-关键帧keyframes
  16. mac os X下的updatedb
  17. 构建Maven父子工程
  18. 自己的mongodb的CRUD封装
  19. java 导出 excel 最佳实践,java 大文件 excel 避免OOM(内存溢出) excel 工具框架
  20. 使用C#重写网上的60行 Javascript 俄罗斯方块源码 (带注释)

热门文章

  1. 还不懂 redis 持久化?看看这个
  2. 『居善地』接口测试 — 4、Requests库发送GET请求
  3. 12.26vj训练补题
  4. 『居善地』接口测试 — 5、使用Requests库发送POST请求
  5. MyBaits自动配置原理
  6. 『动善时』JMeter基础 — 21、HTTP Cookie管理器的使用
  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署
  8. webpack解析(1)
  9. CSS3中的过渡、动画和变换
  10. 【转载】CentOS下查看电脑硬件设备属性命令