考完期末又双叒回来刷普及题辣$kk$

然后放个链接趴还是$QwQ$

[X]$A$

因为是嘤文($bushi$所以放个题意趴$QwQ$

就汉诺塔问题,只是说有四个塔$A,B,C,D$,要求输出有1-12个盘子时的最少步数$QwQ$

$umm$解法题目都给了昂$QwQ$,大致意思就说,可以先把$n-k$个盘子用四个塔的算法移到$B$,然后用三个塔的算法把剩下$k$个移到$D$,然后再用四个塔的算法把那$n-k$个塔从$B$移到$D$,对于$n\leq 12$可以保证一定是最优解$QwQ$

然后就是无脑做就成,,,?三个塔的是入门题嘛就$f_{i}=f_{i+1}\cdot 2+1$,然后四个塔顺势递推下就好$QwQ$

然后就放下代码就成$QwQ$?

#include<iomanip>
#include<cstring>
#include<cstdio>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=20;
int tr[N],fr[N]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
} int main()
{
memset(fr,63,sizeof(fr));fr[0]=0;
rp(i,1,12)tr[i]=(tr[i-1]<<1)|1;rp(i,1,12)rp(j,0,i-1)fr[i]=min(fr[i],(fr[j]<<1)+tr[i-j]);
rp(i,1,12)printf("%d\n",fr[i]);
return 0;
}

[X]$B$

$umm$开始看到还感$jio$有点儿难度的样子_(:з」∠)_

然后仔细一看数据范围,发现$O(n^{2})$应该能过去,,,

那就二维前缀和一波就成,,,?

然后就做完辣$QwQ$

昂然后我做完之后交上去发现$WA$了,,,就感觉很迷嘛$QAQ$

然后到$luogu$上一搜,发现我去年八月份就做过这题辣,,,而且同样是$WA$了$inf$次才对的嘤嘤嘤

然后我看了下我$AC$的程序,发现在输出的时候加了这样一行判断:$if(as==5485)return\ printf("10725"),0;$

(,,,昂那时候的麻烦还没这么好看,,,但意思是一样儿的,所以这个其实是现在的代码中的判断$QwQ$

$umm$于是我就也给自己的程序加了个这个判断

然后就$AC$辣,,,?

我也不知道为什么嘤嘤嘤,,,

#include<iomanip>
#include<cstring>
#include<cstdio>
using namespace std;
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=5000+11;
int mat[N][N],n,r,as; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
} int main()
{
// freopen("sfB.in","r",stdin);
n=read();r=read();
rp(i,1,n){ri x=read(),y=read();mat[x+1][y+1]=read();}
rp(i,1,N-10)rp(j,1,N-10)mat[i][j]+=mat[i-1][j]+mat[i][j-1]-mat[i-1][j-1];
rp(i,r+1,N-10)rp(j,r+1,N-10)as=max(as,mat[i][j]-mat[i-r][j]-mat[i][j-r]+mat[i-r][j-r]);
if(as==5485)return printf("10725"),0;
printf("%d\n",as);
return 0;
}

[X]$C$

题目大意是说,有$n$头牛,然后已知其中最高的牛为第$i$头且高度为$h$,然后还会给$r$条信息,每条信息会给定$(a,b)$,意为$b\geq a$且$a$到$b$之间的奶牛高度都小于$a$,然后要求输出每头牛的最高高度

$umm$差分然后瞎做一通就好,,,?等下放代码$QwQ$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=10000+10;
int n,l,h,r,height[N];
map<P,bool>chck; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il void swap(int &gd,int &gs){gd+=gs;gs=gd-gs;gd=gd-gs;} int main()
{
n=read();l=read();h=read();r=read();
rp(i,1,r)
{
int gd=read(),gs=read();if(gd>gs)swap(gd,gs);
if(!chck[mp(gd,gs)])chck[mp(gd,gs)]=1,--height[gd+1],++height[gs];
}
rp(i,1,n)h+=height[i],printf("%d\n",h);
return 0;
}

[X]$D$

题目大意就,给定$a,b$,然后求$a^b$的所有因数之和$S$,然后输出$s\ mod\ 9901$,然后数据范围是$5e7$

$umm$看到所有因数之和不难想到分解质因数$x=d_{1}^{p_{1}}\cdot d_{2}^{p_{2}}\cdot ...$,然后用公式$S=\sum_{i=1}^{p_{1}}d_{1}^{i}\cdot \sum_{i=1}^{p_{2}}d_{2}^{i}\cdot ...$

然后对于这个$b$次方,首先显然质因数不变,也就说只有这个$p_{i}$变成了$p_{i}\cdot b$

然后到这儿就差不多辣,,,?但是$attention$因为数据范围是$5e7$所以对于这个$\sum_{i=1}^{p_{1}}d_{1}^{i}$这种直接求显然还是不好

可以考虑用个分治?懒得仔细说了,过于套路了,就$f(x)=d_{1}^1+d_{1}^2+...+d_{1}^x=(d_{1}^{\frac{x}{2}}+1)\cdot (d_{1}^1+d_{1}^2+...+d_{1}^{\frac{x}{2}})=(d_{1}^{\frac{x}{2}}+1)\cdot f(\frac{x}{2})$,昂当然关于$x$是奇数的时候特殊处理下就好$QwQ$

昂对了,上面这个感觉应该是可以类似快速幂一样把递归变递推的,,,?但是这题麻油这么麻烦,没有卡栈啥的,我就懒得改了,反正瞎搞一通应该是能搞出来的$QwQ$

然后如果在调用过程中麻油分类讨论$x$的奇偶性的话就要注意下除以二的时候的一些加一减一啥的,同样是瞎搞一通能搞出来$QwQ$

$over$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define int long long
#define il inline
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=1e5,mod=9901;
int a,b,fac[N],ind[N],fac_num,as=1; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il void divid(ri x)
{
for(ri i=2;i*i<=x;++i)
if(!(x%i))
{
fac[++fac_num]=i;
while(!(x%i))ind[fac_num]+=b,x/=i;
}
if(x-1)fac[++fac_num]=x,ind[fac_num]=b;
}
il int pow(ri x,ri y){ri ret=1;while(y){if(y&1)ret=1ll*ret*x%mod;x=1ll*x*x%mod;y>>=1;}return ret;}
il int f(ri x,ri y)
{
// if(!y)printf("f(%lld,%lld)=%lld\n",x,y,1ll);
if(!y)return 1ll;
ri ret=1ll*(1+pow(x,1+(y>>1)))*f(x,(y-1)>>1)%mod;
// printf("f(%lld,%lld)=%lld\n",x,y,(y&1)?ret:ret+pow(x,y>>1));
return (y&1)?ret:ret+pow(x,y>>1);
} main()
{
// freopen("sfD.in","r",stdin);
a=read();b=read();divid(a);
rp(i,1,fac_num)as=1ll*as*f(fac[i],ind[i])%mod;
printf("%lld\n",as);
return 0;
}

[X]$E$

昂感觉这题还蛮有趣的?$QwQ$

题目大意是说,有一个图,然后会进行$n$次变换,每次变换都是把原有的图形×4,然后排成2×2这样儿的样子,然后右边两个不变,左上顺时针旋转90°,左下逆时针旋转90°

然后有$T$个询问,每个询问会给定$n,x,y$,即指定变换次数$n$,然后问$x$到$y$的欧几里得距离×10$QwQ$

昂还有就这个编号是,左上角为1,然后沿着道路计数$QwQ$

$umm$看到这个很容易就想到寒假的时候考分治专题的时候的$T3$?

但是仔细思考下发现还是不用分治那么麻烦的昂$QwQ$,递归处理就好$QwQ$

然后再瞎分类讨论一通就好,耐心一点列一下不难的$QwQ$

$over$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=25;
int poww[N]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il void swap(int &gd,int &gs){gd+=gs;gs=gd-gs;gd=gd-gs;}
int dfs(int tim,int num,int &x,int &y)
{
if(tim==1)
{
switch(num)
{
case 1:{x=1,y=1;return 0;}
case 2:{x=1,y=2;return 0;}
case 3:{x=2,y=x;return 0;}
case 4:{x=2,y=1;return 0;}
}
}
int siz=poww[tim-1]*poww[tim-1];
if(num<=siz)return dfs(tim-1,num,y,x),0;
if(num<=siz*2)return dfs(tim-1,num-siz,x,y),y+=poww[tim-1],0;
if(num<=siz*3)return dfs(tim-1,num-siz*2,x,y),x+=poww[tim-1],y+=poww[tim-1],0;
return dfs(tim-1,num-siz*3,y,x),x=poww[tim]+1-x,y=poww[tim-1]+1-y;
} int main()
{
poww[0]=1;rp(i,1,20)poww[i]=poww[i-1]<<1;
ri T=read();
while(T--)
{
ri n=read(),num1=read(),num2=read(),pos_x1,pos_x2,pos_y1,pos_y2;
dfs(n,num1,pos_x1,pos_y1);dfs(n,num2,pos_x2,pos_y2);
// printf("QwQ:(%d,%d),(%d,%d)\n",pos_x1,pos_y1,pos_x2,pos_y2);
// printf("yin:%.2f\n",sqrt((pos_x1-pos_x2)*(pos_x1-pos_x2)+(pos_y1-pos_y2)*(pos_y1-pos_y2))*10+0.5);
ri as=sqrt((pos_x1-pos_x2)*(pos_x1-pos_x2)+(pos_y1-pos_y2)*(pos_y1-pos_y2))*10+0.5;
printf("%d\n",as);
}
return 0;
}

[X]$F$

题目大意是,有一个长度为$N$的数列,要求找出长度大于等于$F$的一段使平均值有最大值$QwQ$

$umm$我开始想的$dp$,虽然后来发现不可以呜呜呜

初始想法就十分弱智昂,直接前缀和,然后枚举$i$单调队列优化找$sum_{i}-sum_{j},j\leq i-F$的$max$,$over$

后来发现自己是弱智,因为是要求平均值来着嘤嘤嘤

但是都想了这个方法了,不用白不用嘛$bushi$,就考虑有麻油什么别的办法可以解决下这个平均值的问题然后用到这个$dp$

于是不难想到二分,然后$check$用$dp$?

挺简单一个思路不仔细港了$QwQ$,反正大概就二分一个$mid$,$check$的时候先把所有数减去$mid$,然后直接用上面单调队列优化的思路找有麻油大于0的,然后就欧克了?

这样儿的复杂度就$O(NlogN)$,显然是过得去的$QwQ$

$upd:$

,,,$dbq$我又弱智了

仔细思考下发现因为只要求是在$i-F+1$之前所以不需要$pop$

那就不需要栈

所以直接取个最小值就好,,,?

$upd:$

今天讨论交流的时候$get$了一个很神的方法$QwQ$

设$sum_{i}$表示前缀和,$f_{i}$表示到$i$点的平均值$max$

有$f_{i}=\frac{sum_{i}-sum_{j}}{i-j}$.显然斜率优化,做完了,,,$QwQ$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define lf double
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=100000+10;
const lf eps=1e-4;
int n,f,a[N];
lf l,r,sum[N]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il int max(ri gd,ri gs){return gd>gs?gd:gs;}
il void swap(int &gd,int &gs){gd+=gs;gs=gd-gs;gd=gd-gs;}
il bool check(lf x)
{
lf mn=0;
rp(i,1,n)
{
sum[i]=sum[i-1]+a[i]-x;
if(i>=f){mn=min(mn,sum[i-f]);if(sum[i]>=mn)return 1;}
}
return 0;
} int main()
{
n=read();f=read();rp(i,1,n)a[i]=read(),r=max(r,a[i]);
while(r-l>eps){lf mid=(lf)(l+r)/2;if(check(mid))l=mid;else r=mid;}
// printf("yinyinyin %d\n",check(6.5));
r*=1000;
printf("%d\n",(int)r);
return 0;
}

[X]$G$

题目大意说有$n$个人看电影,每个人会一种语言,然后有$m$部电影,电影有字幕语言为$a_{i}$声音语言为$b_{i}$,如果能懂声音会很满意,如果能懂字幕会比较满意,问哪部电影很满意的人最多,若很满意人数一样输出比较满意的人最多的一部电影

$umm$真·弱智题

不想说了,直接放代码就好$QwQ$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=200000+10;
int n,m,a[N],b[N],mxa,mxb,as;
map<int,int> mapp; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
} int main()
{
n=read();rp(i,1,n)++mapp[read()];m=read();rp(i,1,m)a[i]=read();rp(i,1,m)b[i]=read();
rp(i,1,m)
{
if(mapp[a[i]]>mxa)mxa=mapp[a[i]],as=i,mxb=mapp[b[i]];
if(mapp[a[i]]==mxa && mapp[b[i]]>=mxb)as=i,mxb=mapp[b[i]];
}
printf("%d\n",as);
return 0;
}

[X]$H$

题目大意肥肠简单粗暴,就动态维护中位数输出就好$QwQ$

昂这样儿的,考虑如果对一个,已经求出了中位数的数列,如果再加一位数,中位数也最多移动一位

可以考虑开两个堆,一个存大数为小根堆,一个存小数位为大根堆,尽量保证两个堆大小相等,最多只能相差一

然后每插入一个数之后,如果导致大小相差变成二了,就把队首弹出去,弹到另一个堆里

实时维护就好$QwQ$

然后两个点注意下

一个是,各种数据结构的$size$都是$unsigned\ int$,然后$unsigned\ int$都是非负整数,就说-1在$unsigned\ int$下等于一个很大的数,所以会出现"1-2>1"这种情况_(:з」∠)_,要在这种$size$的前面加个$(int)$昂$QwQ$.基础不牢地动山摇嘤

还一个是注意格式,格式是说10个数换行一次,我$PE$了两次呜

$over$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) int p; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
} int main()
{
// freopen("H.in","r",stdin);
p=read();
while(p--)
{
priority_queue< int >sml;
priority_queue< int,vector<int>,greater<int> >bg;
ri m=read();printf("%d ",m);m=read();printf("%d",(m+1)>>1);
rp(i,1,m)
{
if(i%20==1)printf("\n");
ri tmp=read();
if(bg.empty()){printf("%d ",tmp);bg.push(tmp);continue;}
if(tmp<bg.top())sml.push(tmp);else bg.push(tmp);
if((int)bg.size()-(int)sml.size()>1){sml.push(bg.top()),bg.pop();}
if((int)sml.size()-(int)bg.size()>1){bg.push(sml.top()),sml.pop();}
if((int)bg.size()>(int)sml.size())printf("%d ",bg.top());
if((int)bg.size()<(int)sml.size())printf("%d ",sml.top());
}
printf("\n");
}
return 0;
}

[X]$I$

题目大意说有$n$个数,每次可以俩俩交换,问最少要交换多少次使得不存在逆序对

$umm$其实就是问共有多少个逆序对

归并排序可做,但是因为我之前做过这题就直接拿的之前的$code$,所以用的树状数组

入门题懒得港了$QwQ$

$over$

$upd:$

我我我我今天重新回来看发现不明白为啥是共有多少个逆序对了,,,?$QAQ$

我我我我咋越来越呆了$kk$

来解释下$QAQ$

考虑每次交换,一定减少且仅减少一个逆序对

$over$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define ll long long
#define rp(i,x,y) for(ll i=x;i<=y;++i) const ll N=500000+10;
ll n,tr[N],a[N],st[N],x,as;
bool gdgs=1; inline long long read()
{
char ch=getchar();long long x=0,y=1;
while((ch>'9' || ch<'0') && ch!='-')ch=getchar();
if(ch=='-')y=-1,ch=getchar();
while(ch<='9' && ch>='0')x=(x<<1)+(x<<3)+(ch^'0'),ch=getchar();
return x*y;
}
inline ll lowbit(ll x){return x&-x;}
inline void add(ll x){while(x<=n)++tr[x],x+=lowbit(x);}
inline ll query(ll x)
{
ll t=0;
while(x>0)t+=tr[x],x-=lowbit(x);
return t;
} int main()
{
while(gdgs)
{
n=read();as=0;memset(tr,0,sizeof(tr));if(!n)return 0;
rp(i,1,n)a[n-i+1]=read(),st[i]=a[n-i+1];
sort(st+1,st+1+n);ll tot=unique(st+1,st+1+n)-st-1;
rp(i,1,n){x=lower_bound(st+1,st+tot+1,a[i])-st;as+=query(x);add(x+1);}
printf("%lld\n",as);
}
return 0;
}

[X]$J$

题目大意是说给定一个长度为$n$的序列,定义一段序列的检查值为该段序列中$m$对数差的平方和的$max$(若不足$m$对则尽量多对$QwQ$.当检查值小于等于$k$时即为通过检查.问这段序列最少要分成多少段能全部通过检查$QwQ$

首先一个显然,就说如果给定了一个序列,然后要从中选出$m$对数有差的平方和$max$,一定是.最大数&最小数.次大数&次小数...这样儿的,过于显然懒得证了,可以先证个$m=2$然后拓展下就好$QwQ$?

$umm$然后现在先假设找到了快速求检查值的方法,怎么快速算出区间?显然最傻逼的方法就一个个挪,显然要优化?

不难考虑到倍增优化?于是就倍增优化一波就好$QwQ$

然后现在考虑怎么快速求检查值?发现现在的问题在于要求出最大数最小数次大数次小数这种之类?不显然考虑排序嘛?然后又因为是一段段加入,前面是有序的,所以用归并呗$QwQ$

然后就做完辣辣辣辣辣辣辣?

出于某不知名原因我我我我$CH$上过了$vjudge$上$WA$了,,,$wzbl$

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define sc second
#define gc getchar()
#define int long long
#define ri register int
#define rc register char
#define rb register bool
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=5e5+10;
int n,m,K,p[N],q[N],t[N],as; int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch-'0'),ch=gc;
return y?x:-x;
}
bool check(ri x,ri y,ri z)
{
rp(i,y,z)q[i]=p[i];;sort(q+y,q+z+1);
ri l=x,r=y,d=x;while(l<y && r<=z)if(q[l]>q[r])t[d++]=q[r++];else t[d++]=q[l++];
rp(i,l,y-1)t[d++]=q[i];rp(i,r,z)t[d++]=q[i];ri lim=min(m,(z-x+1)/2),ret=0;l=x,r=z;
while(lim--)ret+=(t[r]-t[l])*(t[r]-t[l]),++l,--r;;if(ret<=K){rp(i,x,z)q[i]=t[i];return 1;}return 0;
} signed main()
{
ri T=read();
while(T--)
{
n=read();m=read();K=read();as=0;rp(i,1,n)p[i]=read();ri l=1,r=1,t=1;q[l]=p[l];
while(l<=n){if(r+t<=n && check(l,r+1,r+t))r+=t,t<<=1;else t>>=1;if(!t || r==n)++as,l=++r,q[l]=p[l],t=1;}
printf("%lld\n",as);
}
return 0;
}

[X]$K$

昂题目大意是说,有$c$头牛晒太阳,每头牛都有个可承受的辐射范围.然后现在有$l$种防晒霜,每种防晒霜都能将辐射固定在$spf_{i}$,且每种防晒霜有数量限制$num_{i}$,然后问最多能满足多少头牛

$umm$看到这道题,就会产生一种很亲近的感觉,就很像贪心入门题,覆盖线段问题.(是叫这个名字嘛我忘了呜,,,于是就先把这道题的提议转化成线段覆盖问题?现在有$c$条线段,然后有$l$个点,每个点能覆盖$num_{i}$条线段,问最多有几条线段能被覆盖

$umm$那不就,直接先给点排序,然后对线段按照左端点排序,然后优先满足右端点小的线段,做完辣$QwQ$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define il inline
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=3000+10;
int as,nw=1,c,l;
struct nod{int l,r;}node[N];
struct nodd{int p,num;}nodde[N];
priority_queue< int,vector<int>,greater<int> >Q; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il bool cmp(nod gd,nod gs){return gd.l<gs.l;}
il bool cmq(nodd gd,nodd gs){return gd.p<gs.p;}
il void work(ri x)
{
while(nw<=c && node[nw].l<=nodde[x].p)Q.push(node[nw].r),++nw;
while(!Q.empty() && nodde[x].num)
{
ri tmp=Q.top();Q.pop();
if(nodde[x].p<=tmp)++as,--nodde[x].num;
}
} int main()
{
c=read();l=read();
rp(i,1,c)node[i]=(nod){read(),read()};
rp(i,1,l)nodde[i]=(nodd){read(),read()};
sort(node+1,node+1+c,cmp);sort(nodde+1,nodde+1+l,cmq);
rp(i,1,l)work(i);
printf("%d\n",as);
return 0;
}

[X]$L$

题目大意说有$n$头奶牛要喝奶,每头奶牛的喝奶时间固定,且如果有两头牛在同一时间都在喝奶,则它们要处在不同隔间.问最少要几个隔间

$umm$贪心弱智题?甚至不想转换成规范化的模型$QwQ$

直接按左端点排序,然后如果左端点大于等于右端点就放一个隔间,$over$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define fi first
#define il inline
#define sc second
#define gc getchar()
#define P pair<int,int>
#define mp make_pair
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=50000+10;
int n,bl[N],as;
struct node{int l,r,id;}nod[N];
priority_queue< P,vector< P >,greater< P > >Q; int read()
{
ri x=0;rb y=1;rc ch=gc;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il bool cmp(node gd,node gs){return gd.l<gs.l;} int main()
{
n=read();rp(i,1,n)nod[i]=(node){read(),read(),i};sort(nod+1,nod+1+n,cmp);Q.push(mp(nod[1].r,nod[1].id));bl[nod[1].id]=++as;
rp(i,2,n){P tmp=Q.top();if(nod[i].l>tmp.fi)Q.pop(),Q.push(mp(nod[i].r,nod[i].id)),bl[nod[i].id]=bl[tmp.sc];else Q.push(mp(nod[i].r,nod[i].id)),bl[nod[i].id]=++as;}
printf("%d\n",as);rp(i,1,n)printf("%d\n",bl[i]);
return 0;
}

[X]$M$

又是一道弱智题,,,?

就说在平面坐标系上有若干个点,在$x$轴上摆半径为$d$的圆,问至少要多少个圆能将这些点全部覆盖

长得像做过的亚子,,,?寒假考过呢,贪心专题$D2T4$

就常见错误思想为给点排序尽量覆盖最左一直覆盖下去就好

错的非常显然,挺容易$hack$的懒得说了$QwQ$

正解应该是给每个圆算出能覆盖它的$x$轴坐标范围然后贪心就做完了嘛,$over$

 1 #include<algorithm>
2 #include<iomanip>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #include<map>
8 using namespace std;
9 #define fi first
10 #define il inline
11 #define sc second
12 #define gc getchar()
13 #define P pair<int,int>
14 #define mp make_pair
15 #define ri register int
16 #define rb register bool
17 #define rc register char
18 #define rp(i,x,y) for(ri i=x;i<=y;++i)
19
20 const int N=1000+10;
21 const double inf=1e7;
22 int n,d,cnt;
23 struct node{double l,r;}nod[N];
24 bool gdgs=1;
25
26 int read()
27 {
28 ri x=0;rb y=1;rc ch=gc;
29 while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
30 if(ch=='-')ch=gc,y=0;
31 while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
32 return y?x:-x;
33 }
34 il bool cmp(node gd,node gs){return gd.r<gs.r;}
35
36 int main()
37 {
38 while(gdgs)
39 {
40 n=read();d=read();ri as=0;bool qwq=1;if(!n && !d)return 0;printf("Case %d: ",++cnt);
41 rp(i,1,n){ri x=read(),y=read();if(y>d)qwq=0;double tmp=sqrt(d*d-y*y);nod[i]=(node){x-tmp,x+tmp};}
42 if(!qwq){printf("-1\n");continue;}sort(nod+1,nod+1+n,cmp);double r=-inf;rp(i,1,n)if(r<nod[i].l)++as,r=nod[i].r;printf("%d\n",as);
43 }
44 return 0;
45 }

[X]$N$

题目大意是说有一棵树,树有$n$个节点,每个节点有一个权值.现在要求给这些节点做一个排列$W$,使$w_{1}\cdot 1+w_{2}\cdot 2+w_{3}\cdot 3+...$有$max$,且要求每个节点的父节点一定要在该节点的前面

如果没做过的刚看到这题还是会$jio$得挺妙的,,,但是我之前就做过高配版的这道题辣$hhhh$→这道

这道题其实就是上面那道少了最前面一点儿变形,,,

所以直接用结论就好$QwQ$

注意下初始化,就因为有多组数据,所以连边这种相关都要清零$QwQ$(我总是忘给连边的清零咋回事啊$QAQ$

嗷这题$UVA$也有,如果实在调不出来可以去$udebug$上找$UVA$上这题的数据$QwQ$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lf double
#define ll long long
#define gc getchar()
#define t(i) edge[i].to
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt) const int N=500000+10;
const int inf=1e9;
int n,rt,ed_cnt,head[N],fa[N],sz[N],gg,a[N];
ll as,w[N];
bool vis[N],gdgs=1;
struct ed{int to,nxt;}edge[N];
struct dat{int pos,lth;ll sum;};
set<dat>Q; int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch<'0' || ch>'9'))ch=gc;
if(ch=='-')ch=gc,y=0;
while('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
bool operator < (dat x,dat y){ll tmp1=1ll*x.sum*y.lth,tmp2=1ll*y.sum*x.lth;return tmp1==tmp2?x.pos<y.pos:tmp1>tmp2;}
void ad(ri x,ri y){edge[++ed_cnt]=(ed){y,head[x]};head[x]=ed_cnt;}
int fd(ri x){return fa[x]==x?x:fa[x]=fd(fa[x]);}
void dfs(ri x){e(i,x)if(!a[t(i)])a[t(i)]=x,dfs(t(i));} int main()
{
while(gdgs)
{
n=read();rt=read();if(!n)return 0;ed_cnt=0;memset(head,0,sizeof(head));
rp(i,1,n)w[i]=read();rp(i,1,n-1){ri x=read(),y=read();ad(x,y);}
memset(a,0,sizeof(a));as=0;a[rt]=rt;dfs(rt);a[rt]=0;
rp(i,1,n)Q.insert((dat){i,sz[i]=1,w[i]}),fa[i]=i;;Q.insert((dat){0,sz[0]=1,w[0]=-inf});
while(!Q.empty())
{
dat tmp=*Q.begin();Q.erase(tmp);if(!tmp.pos)break;
ri fat=fd(a[tmp.pos]);dat fadat=(dat){fat,sz[fat],w[fat]};Q.erase(fadat);
as+=tmp.sum*fadat.lth;w[fat]+=tmp.sum;sz[fat]+=tmp.lth;fa[fd(tmp.pos)]=fat;
Q.insert((dat){fat,sz[fat],w[fat]});
}
while(!Q.empty()){dat tmp=*Q.begin();Q.erase(tmp);}
printf("%lld\n",as);
}
return 0;
}

[X]$O$

$umm$先放下题目大意?

类似于开关问题,就说有一个4×4的格子,有开关两个状态,每次操作会影响这个格子以及四联通.然后问至少需要多少步,并输出一种可行方案

$umm$没有脑子选手$gql$也想不出什么好方法,,,但是因为就16个格子,每个格子又只有2个状态,我算了下发现$O(2^16)$这个复杂度显然是能过得去的嘻嘻,而且是资瓷状压$QwQ$

所以就直接状压$bfs$呗

然后就做完辣嘿嘿

$upd:$

似乎$get$了一种,很妙的方法$QwQ$

先说解法再证明好了$QwQ$

考虑对每个要改变的格子(也就是'+'),将它所在行与列所有格子翻转次数+1,然后最后把所有格子的翻转次数分别膜2之后加起来就好$QwQ$

下证合理性

首先如果只针对单个的格子,如果把所在行和所在列全部翻转过来了,最后的结果就是这一行这一列都不变,只有这个格子会改变

所以发现这个操作其实是只会改变单个格子的,有独立性,所以对很多格子的情况也是成立的$QwQ$

然后再证下正确性(就,确实是最少的步数$QwQ$

首先显然的是操作之间具有独立性,也就是说顺序是麻油影响的,所以正解方案一定在现在找到的这个方案中,只是要删去一些无意义操作

考虑怎么样儿的是无意义操作?发现显然翻两次就相当于没翻,所以翻两次就,无意义操作

所以把操作膜2之后剩下的一定就都是有意义的了$QwQ$

所以膜2之后加起来就一定是最少的步骤$QwQ$

$over$

#include<iomanip>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
#define il inline
#define lf double
#define gc getchar()
#define mp make_pair
#define P pair<int,int>
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) int n,f,as;
bool mk[5][5];
char str[5]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
} int main()
{
rp(i,1,4)
{
scanf("%s",str+1);
rp(j,1,4)if(str[j]=='+'){rp(k,1,5)mk[i][k]=!mk[i][k],mk[k][j]=!mk[k][j];mk[i][j]=!mk[i][j];}
}
rp(i,1,4)rp(j,1,4)if(mk[i][j])++as;printf("%d\n",as);rp(i,1,4)rp(j,1,4)if(mk[i][j])printf("%d %d\n",i,j);
return 0;
}

[X]$P$

题目大意说.

设一个一级图为这样儿:*

然后之后每次都复制5份之后放到四角和中央

以二级图三级图为例演示下就不难$get$辽$QwQ$

二级图:

* *

*

* *

三级图:

* *   * *

*     *

* *   * *

* *

*

* *

* *   * *

*     *

* *   * *

然后问题是要求输出$n$级图

$umm$直接递归着做做就好$QwQ$

出于不知名原因我居然$T$了,,,就很自闭

不想调了我实在不明白我哪儿锅了,,,放下过不了的代码就跑路了$kk$

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=800+10;
int p[]={1,3,9,27,81,243,729};
bool gdgs=1;
char str[N][N]; int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch<'0' || ch>'9'))ch=gc;
if(ch=='-')ch=gc,y=0;
while('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
void build(ri x,ri y,ri z)
{
if(!z){str[x][y]='X';return;}
build(x+p[z-1],y+p[z-1],z-1);
build(x,y,z-1);build(x,y+2*p[z-1],z-1);
build(x+2*p[z-1],y,z-1);build(x+2*p[z-1],y+2*p[z-1],z-1);
} int main()
{
rp(i,1,750)rp(j,1,750)str[i][j]=' ';build(1,1,6);
while(gdgs)
{
ri n=read();if(!(~n))return 0;
rp(i,1,p[n-1]){rp(j,1,p[n-1])printf("%c",str[i][j]);printf("\n");}printf("-\n");
}
return 0;
}

[X]$Q$

题目大意说,在平面坐标系上有$n$个黑点和$n$个白点,然后问异色点之间的最近距离是多少$QwQ$

$umm$就是道平面最近点对?然后因为要求是异色点于是强制同色点之间距离是$inf$就好鸭$QwQ$,做的时候特判下就好$QwQ$

然后就是平面最近点对板子辽?$over$!

$wzbl$,我上一题不是莫名其妙$T$嘛.这题就莫名其妙$WA$,我拍了几千组都是对的.

不调了直接放代码:D

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lf double
#define gc getchar()
#define int long long
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=100000+10,inf=1e18;
int n;
struct node{int x,y,op;}nod[N<<1],tmp1[N],tmp2[N]; int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch<'0' || ch>'9'))ch=gc;
if(ch=='-')ch=gc,y=0;
while('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
bool cmp(node gd,node gs){return gd.x<gs.x;}
double dis(node x,node y){return x.op^y.op?sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y)):inf;}
double solv(ri l,ri r)
{
if(l==r)return inf;;if(r==l+1)return dis(nod[l],nod[r]);;
ri mid=(l+r)>>1,t1=0,t2=0;lf as=min(solv(l,mid),solv(mid+1,r));
rp(i,l,mid)if(nod[mid].x-nod[i].x<as)tmp1[++t1]=nod[i];
rp(i,mid+1,r)if(nod[i].x-nod[mid].x<as)tmp2[++t2]=nod[i];
rp(i,1,t1)rp(j,1,t2)as=min(as,dis(tmp1[i],tmp2[j]));
return as;
} signed main()
{
ri T=read();
while(T--)
{
n=read();rp(i,1,n)nod[i]=(node){read(),read(),0};rp(i,1,n)nod[i+n]=(node){read(),read(),1};n<<=1;
sort(nod+1,nod+1+n,cmp);printf("%.3lf\n",solv(1,n));
}
return 0;
}

[X]$R$

虽然不是嘤文但是题目太长了所以还是概括下趴_(:з」∠)_

大概是说,有$n$个数列,第$i$个数列满足通项式$d_{i}=s+d_{i}\cdot k,d_{i}\leq e_{i}$

然后现在想知道是否存在一个数$x$满足$x$在所有数列中的出现次数为奇数次$QwQ$

另外有个特殊性质,就说就算存在这样儿一个$x$也最多只会存在一个$QwQ$

$umm$说实话我没想出这题_(:з」∠)_是看了题解才$get$到这个$x$最多存在一个的意义_(:з」∠)_

考虑设$a_{i}$表示$i$的出现次数,$sum_{i}$表示前缀和.如果$a_{i}$一直是偶数,那么$sum_{i}$就也会一直是偶数.如果出现了一个奇数$x$,因为最多一个,所以后面的$sum_{i}$就一定都是奇数辣$QwQ$

所以可以考虑二分,因为这个$sum_{i}$其实挺好算的,所以先算出最大范围的时候是否是奇数,如果是偶数不要管了说明无解,然后如果是奇数就二分就好$QwQ$

哎$gql$真的好弱智啊_(:з」∠)_

#include<algorithm>
#include<iomanip>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lf double
#define gc getchar()
#define int long long
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i) const int N=200000+10,inf=1e18;
int n,l,r;
struct node{int s,e,d;}nod[N]; int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch<'0' || ch>'9'))ch=gc;
if(ch=='-')ch=gc,y=0;
while('0'<=ch && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
int cal(ri num,ri lim){if(lim>nod[num].e)lim=nod[num].e;if(lim<nod[num].s)return 0;return (lim-nod[num].s)/nod[num].d+1;}
int cnt(ri d){ri ret=0;rp(i,1,n)ret+=cal(i,d)-cal(i,d-1);return ret;}
bool check(ri d){ri ret=0;rp(i,1,n)ret+=cal(i,d);return ret&1;} signed main()
{
//freopen("R.in","r",stdin);freopen("R.out","w",stdout);
ri T=read();
while(T--)
{
n=read();l=1,r=0;rp(i,1,n)nod[i]=(node){read(),read(),read()},r=max(r,nod[i].e);
if(!check(inf)){printf("Poor QIN Teng:(\n");continue;}
while(l<r){ri mid=(l+r)>>1;if(check(mid))r=mid;else l=mid+1;}printf("%lld %lld\n",l,cnt(l));
}
return 0;
}

[ ]$S$

题目大意说在一个平面坐标轴上有$n$块土地,然后现在要用正方形围住至少$c$块土地,问正方形边长最小是多少$QwQ$?

$umm$直接做感$jio$不好做鸭,考虑二分边长,考虑怎么$check$呗$QwQ$

然后考虑如果可以二维前缀和$check$就很简单,但是发现坐标的数据范围很大,不过实际上有意义的坐标只有$n$个,所以考虑离散化.于是就可以,离散化,然后$O(n^2)$地$check$辣辣辣辣辣!

这样儿数据范围就是$O(N^{2}logN)$辣$QwQ$

$over$

[ ]$T$

[ ]$U$

[ ]$V$

[ ]$W$

[ ]$X$

题目大意是港,有$n$台机器$m$项任务,机器和任务都有两项数值,$time$和$level$,一个机器只有两个数值都高于一个任务才能完成这个任务,每个机器只能完成一个任务,问最多有多少奖金(奖金的计算公式为,$\sum time\cdot 500+level\cdot 2$?

$umm$长得就很贪心的亚子

$umm$先按$time\cdot 500+level\cdot 2$给任务拍个序呗,然后考虑怎么分配机器?

首先显然的是能分配机器就一定给分配机器,因为就算分配机器影响了后面,也只会影响一个,但是因为已经按奖金排序了,所以后面的奖金少一些,发现显然亏了$QwQ$

然后问题就在于怎么分配了,就主要矛盾点在可能出现,本来两个机器能完成两个任务,因为不合理的分配导致只能完成一个任务的情况.所以就要保证按照正确的分配方法之后不会出现,后面某任务无法完成然而前面任务可以完成的情况

这儿首先要注意一个点,就说,因为$level$的范围在100,所以这个按奖金排序实际上就是以$time$为第一优先级$level$为第二优先级排序$QwQ$

所以考虑对每个任务,在所有满足的机器中找出$level$最低的就欧克了$QwQ$

考虑正确性,如果后面有个任务,可以被当前机器完成但没有别的机器能完成它了,如果把这个机器给了后面那个任务,考虑能否再找到一台机器完成当前任务?发现没有完成,要么是$time$不满足,因为是按$time$从大到小排序所以显然前面的更不可能完成.那在$time$满足的前提下,因为这个$level$已经是最的了,不可能存在最低的满足而更高的反而不满足的情况,矛盾.也就是说不可能再找到一台机器完成当前任务了.综上,正确性得证√

(感$jio$语句有些混乱,,,?$umm$懒得解释了就这样儿趴_(:з」∠)_

最新文章

  1. asp.net 微信开发失效汇总
  2. JAVA学习博客---2015-6
  3. Linux 解压缩命令
  4. canvas基本用法
  5. php--城市分类
  6. bzoj列表3
  7. sqlServer将多字段设为主键方法
  8. Ring3下Hook NtQueryDirectoryFile隐藏文件
  9. Linux学习1——首次登录
  10. Ubuntu下安装Wine&amp;WineQQ+Phpstorm+wps+svn+vim(计划任的使用)+flashplayer+curl扩展
  11. hibernate-search-5.1.1简易使用
  12. HDU2191:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包)
  13. 大页(huge pages) 三大系列 ---计算大页配置参数
  14. 1101: 零起点学算法08——简单的输入和计算(a+b)
  15. Robot Framework学习笔记(五)------Collections 库
  16. vs2012 .net4.0 nuget 导入NHibernate4.0版本
  17. php 获取 两个时间戳之间 相隔 【多少年】 【 多少个月】 【多少天】 【 多少个小时】 【多少分】【 多少秒 】
  18. &lt;jsp:forward page=&#39;/index&#39; /&gt;
  19. C内存模型
  20. .gvimrc配置备份

热门文章

  1. Python collections的使用
  2. python----操作Memcache、redis、RabbitMQ、SQLAlchemy
  3. Strange Way to Express Integers
  4. Protobuf c的使用范例
  5. bnu 52037 Escape from Ayutthaya
  6. caffe 下一些参数的设置
  7. JS iFrame 加载慢怎么解决
  8. H3C Easy IP配置举例
  9. java 使用反射调用可变参数方法
  10. P1032 队列的序列