CODEFORCES ROUND#624 DIV3

此次比賽從名字就能夠看出很是水,然鵝由於第一次打codeforces不太熟悉操做只來的及作簽到題(還錯了一次)node


A,B,C都是簽到題考點思惟就不寫了ios

D題

https://codeforces.ml/problemset/problem/1311/D

題目大意是:有t組數據每組數據給你三個數,a,b,c每次一個數加一或數組

者減一都算一次操做(不能爲變負數),問最小的操做次數構造出A,優化

B,C使b%a==0,c%b==0。spa

t<1000,a,b,c<1e4 時限2scode

首先想到是找b的倍數與a,c最近的數再直接加減排序

再一看時限兩秒。。。果斷暴力get

而後就枚舉這樣的數對A,B,C,答案就是其a,b,c的差的最小值string

#代碼後面有時間再補

E題

https://codeforces.ml/contest/1311/problem/E

奈何本人沒文化,題目沒怎麼懂,往後有時間再補(flag)

接下來纔是重頭戲it


F題

https://codeforces.ml/problemset/problem/1311/F

題目大意:給你n(<2e5)個點a1,a2,...,an在同一個數軸上,保證座標不會重複, 每一個點有一個固定的速度(-1e8到1e8),對某一個t時刻,某兩個點距離最小,輸出這些最小值之和(min d(i,j)i<j之和)

容易先想到將a按座標排序,xi<xj,vi<vj那d(i,j)確定不會減少則min d(i,j)=xj-xi,若是vi>vj 則min d(i,j)=0


暴力n^2代碼很簡單

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n;
long long tot;
struct node
{
	long long x,v; 
}a[N]; 
bool cmp(node x,node y)
{
	return x.x<y.x;
}
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);
	sort(a+1,a+n+1,cmp);
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<i;j++)
		{
			if(a[i].v>=a[j].v)
			{
				tot+=a[i].x-a[j].x;
			}
		}
	}
	printf("%lld",tot);
	return 0;
}

由於ans+=xi⋅cnt−sum能夠將每次枚舉當作從當前新建的數組中添加一個元素,由於從小到大遍歷的因此速度小於i而x大於i的必定尚未被加入新建的數組因此此想法能夠算出知足條件的num和tot。

具體作法是新建兩個數組q,p開始都爲空,第一個數組q[i]表明a[1~i].v中速度爲q的a[1~i].x(座標)的和,第二個數組p[i]表明速度爲p[i]的個數而這能夠用樹狀數組優化。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int n,m,pos,v[N];
long long tot,s[N][2];
struct node
{
	long long x,v; 
}a[N]; 
bool cmp(node x,node y)
{
	return x.x<y.x;
}
int lowbit(int x)
{
	return x&(-x);
}
void update(int x,int val)//更新數組 
{
	while(x<=n)
	{
		s[x][0]++;
		s[x][1]+=val;
		x+=lowbit(x);//從x往上更新全部q,p數組有關a[x]的值 
	}
}
long long getsum(int x,int flag)//獲取數組1~x的和 
{
	long long res=0;
	while(x)
	{
		res+=s[x][flag];
		x-=lowbit(x);	//從x往下加故是減號 
	}	
	return res;
}
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);
		v[i]=a[i].v;
	}
	sort(a+1,a+n+1,cmp);
	sort(v+1,v+n+1);
	m=unique(v+1,v+n+1)-v-1;
	for(int i=1;i<=n;i++)
	{
		pos=lower_bound(v+1,v+m+1,a[i].v)-v;
		tot+=getsum(pos,0)*a[i].x-getsum(pos,1);//s[][0]表明p[i],s[][1]表明q[i] 
		update(pos,a[i].x);
	}
	printf("%lld",tot);
	return 0;
}
相關文章
相關標籤/搜索