题意:给 a b c 你现在可以对这三个数进行+1 -1 操作 问最少操作后使得 a整除b b整除c
做法:暴力枚举 a和b 就可以了,注意范围 容易被hack
#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=2e5+10;
int n,m;
ll a,b,c;
ll A,B,C;
ll mx;
void cal(int i,int j,int k)
{
int t=abs(a-i)+abs(b-j)+abs(k-c);
if(t>_;while(_--)
{
scanf("%lld%lld%lld",&a,&b,&c);
mx=0x3f3f3f3f3f3f3f3f;
for(ll i=1;i<=2e4;++i){
for(ll j=i;j<=2e4;j+=i){
ll x=i,y=j,z=c/y*y;
if(z>=y) cal(x,y,z);
z=(c/y+1)*y;
cal(x,y,z);
}
}
printf("%lld\n",mx);
printf("%lld %lld %lld\n",A,B,C);
}
}
题意:输入n d 代表树的n个节点,每个节点在树上都有一个深度,现在要你构造二叉树 使得所有节点的度之和等于d。
不存在输出NO
思路:思路很简单,先构造一条单链,然后可以考虑从最底下 或者从最上面 取一个点往上移,我这里是从上面选一个点。
代码参考 来自 jiufeng 的提交代码
就是怎么模拟写比较的复杂。
#include
#define LL long long
#define PB push_back
#define POP pop_back()
#define PII pair
#define ULL unsigned long long
using namespace std;
const int INF=0x3f3f3f3f;
const double pi=acos(-1),eps=1e-10;
const int maxn=1<<17;
const int N=5e3+10,M=N*40;
int n,d;
int fa[N];
int son[N];
int de[N];//某层的空置位
int dp[N];//dp[i]: i节点在dp[i]层
int main()
{
de[1]=1;
int t;
cin>>t;
while(t--){
scanf("%d%d",&n,&d);
memset(de,0,sizeof(de));
de[1]=1;
int s=0;
for(int i=1;i<=n;i++)s+=i-1;//一条链
int now=1;
for(int i=1;i<=n;i++){
dp[i]=dp[i-1]+1;//下一个节点在i-1的下一层
de[dp[i]]--;//单链 去掉这层的一个空置位
if(s-(n-i+1)>=d){//i节点往上跳一层,后面的全部往上跳一层,所以是n-i+1
//printf("i:%d n-i+1:%d d:%d\n",i,n-i+1,d);
if(de[dp[i]-1]){//因为是往上跳一层,那么看上一层的空置位是否有
s-=(n-i+1);
de[dp[i]-1]--;//挂在dp[i]-1 层上,所以de[dp[i]-1]的空置位减一
de[dp[i]]++;//dp[i]层的空置位+1 抵消掉32行的减一
dp[i]--;//i节点成功到达 上一层
}
}
de[dp[i]+1]+=2;
//cout<
题意:给定n个位置xi 以及n个速度vi 位置变化为x=vi*t+xi,现在要你求两两点距离和最小,这题容易读成 所有点的t是一致,其实不然 每个点的时间是不一样的,而且每对点的时间也是不一样的。
相当于是求任意两个点最近的距离时的距离和
做法:将x从大到小排个序,按照v 离散化在线段树上查找 x比自己小 v 比自己大的点,因为这些点可以跟这个点重合。
那么答案 就是先求所有点对的距离和-能重合的距离点对距离和
#include
using namespace std;
typedef long long ll;
const int N=2e5+10;
struct node
{
ll x,v;
}a[N];
ll X[N],len;
int n;
bool cmp(node a,node b)
{
return a.x>1;
if(pos<=mid) up(id<<1,l,mid,pos,val);
else up(id<<1|1,mid+1,r,pos,val);
s1[id]=s1[id<<1]+s1[id<<1|1];
s2[id]=s2[id<<1]+s2[id<<1|1];
}
void qu(int id,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr){
sum+=s1[id];
num+=s2[id];
return ;
}
int mid=l+r>>1;
if(ql<=mid) qu(id<<1,l,mid,ql,qr);
if(qr>mid) qu(id<<1|1,mid+1,r,ql,qr);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%lld",&a[i].x);
for(int i=1;i<=n;++i) {
scanf("%lld",&a[i].v);
X[++len]=a[i].v;
}
sort(X+1,X+1+len);
len=unique(X+1,X+1+len)-X-1;
sort(a+1,a+1+n,cmp);
ans=0,num=1,x1=a[1].x,sum=0;
for(int i=2;i<=n;++i){
ans+=num*(a[i].x-x1)-sum;
sum+=a[i].x-x1;
num++;
}
//printf("ans:%lld\n",ans);
num=0,sum=0;
for(int i=1;i<=n;++i){
a[i].v=getid(a[i].v);
if(i==1){
up(1,1,len,a[i].v,a[i].x-x1);
continue;
}
num=0,sum=0;
if(a[i].v