嗯没错我就是又炸了
水一波题解
(1)split
给定
n,k
;
如果
n
能被分成相差为
则分
对两块进行相同的处理
求能分成多少块
n≤109
啊对啊其实题面就是题解
然而我傻逼地写了一个计算对应大小的块的贡献
还搭配着奇数特判才勉强A掉…
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
int n,k,ans,tmp;
int ksm(int a,int b){
int ret=1;
while(b){
if(b&1) ret*=a;
b>>=1;
a*=a;
}
return ret;
}
int check(int a,int b){
while(a<b) a*=2;
return a;
}
signed main(){
n=read();k=read();
ans=1;
if(k%2){
tmp=n;
while(tmp>k){
if(!((tmp-k)%2)) ++ans;
else break;
tmp=(((tmp+k)/2)%2)?(tmp+k)/2:(tmp-k)/2;
}
write(ans);
return 0;
}else{
for(int i=0;(n-k*(2*i+1))>=check(2,2*i+1);++i){
if(!((n-k*(2*i+1))%check(2,2*i+1))) ++ans;
int d=check(2,2*i+1)<<1;
for(int j=1;(n-k*(2*i+1))>=d;++j){
if(!(((n-k*(2*i+1)))%d)) ++ans;
d<<=1;
}
}
write(ans);
return 0;
}
}
(2)run
n
人于长为
编号大的碰到编号小的便淘汰编号小的
求比赛进行时间,用分数表示
n≤105
很显然有一种
n2
暴力
我们可以用链表和堆优化
wuvin的所谓 O(n) 做法貌似有锅啊
%%%ksda47832338
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#include<bitset>
#include<queue>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 111111
int l,T;
const double inf=1e30;
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
struct data{
int u, d;
void standard(){
int x;
if(d<0) u=-u,d=-d;
x=gcd(u,d);
u/=x,d/=x;
}
operator double()const{ return d?(double)u/d:inf;}
data(){}
data(int x, int y) {
int a;
if(y<0) x=-x,y=-y;
a=gcd(x,y);
u=x/a;
d=y/a;
}
};
struct penguin{
int id;
int d, v, last, next;
bool operator <(const penguin &a) const{ return d<a.d; }
inline void cut();
}pen[stan];
void penguin::cut() {
pen[last].next = next;
pen[next].last = last;
}
inline data getIntersect(int i, int j){
int v1=pen[i].v,s1=pen[i].d;
int v2=pen[j].v,s2=pen[j].d;
if(v1>v2&&s1>s2) s1-=l;
else if(v2>v1&&s2>s1) s2-=l;
return data(s1-s2,v2-v1);
}
struct Pair{
int a,b;
data t;
Pair(){}
Pair(int _a, int _b):a(_a),b(_b),t(getIntersect(_a,_b)){}
bool operator < (const Pair &p)const{ return t > p.t; }
};
bitset<stan>bits;
priority_queue<Pair>que;
int main(){
T=read();
while(T--){
Pair t;
int n=read();
l=read();
for(int i=1;i<=n;++i)
pen[i].d=read(),pen[i].id=i;
for(int i=1;i<=n;++i)
pen[i].v=read();
sort(pen+1,pen+n+1);
bits.reset();
while(!que.empty()) que.pop();
que.push(Pair(1,2));
pen[1].last=n,pen[1].next=2;
que.push(Pair(n,1));
pen[n].last=n-1,pen[n].next=1;
for(int i=2;i<n;++i){
que.push(Pair(i,i+1));
pen[i].last=i-1;
pen[i].next=i+1;
}
while(!que.empty()) {
t = que.top();
que.pop();
if(bits.test(t.a) || bits.test(t.b)) continue;
if(pen[t.a].id < pen[t.b].id) {
if(pen[t.a].last==t.b) break;
que.push(Pair(pen[t.a].last, t.b));
pen[t.a].cut();
bits.set(t.a);
}else {
if(t.a==pen[t.b].next) break;
que.push(Pair(t.a, pen[t.b].next));
pen[t.b].cut();
bits.set(t.b);
};
}
write(t.t.u);putchar('/');write(t.t.d);
puts("");
}
return 0;
}
(3)wall
给一个图,有
n
个端点与
每条边有两个对应端点与权值
其中某些边在平面上围成了一个封闭的区块
求拆除最少的边破除所有封闭的区块
如果有多种方案,求权值最小的一种
考场上光顾着调第二题去了
裸的最大生成树
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 111111
#define sten 333333
int T,n,m,cnt,a,ans,fa[stan];
struct e{
int a,b,c;
}edge[sten];
bool cmp(e a,e b){
return a.c>b.c;
}
int getfa(int x){
if(fa[x]==x) return x;
else return fa[x]=getfa(fa[x]);
}
signed main(){
T=read();
while(T--){
cnt=0;ans=0;
n=read();m=read();
for(int i=1;i<=n;++i)
fa[i]=i;
for(int i=1;i<=n;++i){
a=read();
a=read();
}
for(int i=1;i<=m;++i){
edge[i].a=read();
edge[i].b=read();
edge[i].c=read();
ans+=edge[i].c;
}
sort(edge+1,edge+m+1,cmp);
for(int i=1;i<=m;++i){
int x=getfa(edge[i].a);
int y=getfa(edge[i].b);
if(x!=y){
fa[x]=y;
++cnt;
ans-=edge[i].c;
}
}
write(m-cnt);putchar(' ');write(ans);
puts("");
}
return 0;
}
return 0;