1. 程式人生 > >079C.D Decrease 構造+思維

079C.D Decrease 構造+思維

等於 ont long long nbsp 減法 c++ bsp name n)

題意:op:選出最大值減去n,其余值加上1. 構造出長度為n的序列,使得其經過k次操作後,每個元素都小於等於n-1. k<=1e16

逆操作:選一個元素加上n,其余減去1.(經過逆操作後,加上n個要為最大,其余不能<0)
k次操作後每個元素都小於等於n,最後的序列若能經過k次合法的逆操作就能得到答案.
構造最後的序列為
:0,1,2...n-1 k=0
:n,0,1...n-2 k=1
:n-1,n,0,.n-3 k=2
.....
2,3,4.....0 k=n-1.
1,2,3.....n k=n 經過n次操作後的序列和初始偏差一
則最後的序列開頭為k/n...剩下k%n個操作暴力即可.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+20;
const ll inf=1e16+1000;
ll k,n,a[N];
int main()
{
	while(cin>>k)
	{
		n=50;
		ll num=k/n,re=k%n;
		for(int i=1;i<=n;i++)
			a[i]=num+i-1;
		for(int p=1;p<=re;p++)
		{
			for(int i=1;i<=n;i++)
			{
				if(i==p)
					a[i]+=n;
				else
					a[i]--;
			}
		}
		printf("%lld\n",n);
		for(ll i=1;i<=n;i++)
			printf("%lld%c",a[i],i==n?‘\n‘:‘ ‘);
	}
	return 0;
}
//25720164523
//154320986863
//500000000000000000

  


題意:操作如上題,給出長度為n的序列a[i],為經過多少次操作後每個元素的值都小於等於n-1.
n<=50 a[i]<=1e16。

每次操作總和減小1,l=sum-n*(n-1) r=sum n^2枚舉ans
等價操作:先給每個元素加上x後,還剩下x次減n+1操作.

若有元素大於n-1則 肯定要用減法 判斷使用次數是否超過即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+20;
const ll inf=1e16+1000;
ll a[N];
int n; int main() { while(cin>>n) { ll sum=0; for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i]; ll l=sum-n*(n-1),r=sum; for(ll k=l;k<=r;k++) { if(k<0) continue; ll res=0; bool ok=true;
for(int i=1;i<=n;i++) { ll dif=max(0ll,a[i]+k-n+1); ll x=dif/(n+1); if(dif%(n+1)) x++; res+=x; } if(res==k) { cout<<res<<endl; break; } } } return 0; } //25720164523 //154320986863 //500000000000000000

079C.D Decrease 構造+思維