【比賽報告】2018.10.23校賽[【Nescafé 18】杯模擬賽] NOIP練習賽十八

比賽時間:2018.10.22 選手:lrllrl 得分:100+0+0=100 用時:2h


在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述


首先判斷可行性很好辦,看能不能整除就好了。
我們單獨考慮行(無環情況下)。
設每行 ii 的目標攤位數目爲 cntr[i]cntr[i]cntr[i]cntr[i] 的前綴和爲 sumr[i]sumr[i] ,即sumr[i]=j=1icntr[j]sumr[i]=\sum_{j=1}^icntr[j]
最少步數爲 i=1ni×tnsumr[i]\sum_{i=1}^n\left| i\times\frac{t}{n}-sumr[i]\right|
r[i]=cntr[i]tnr[i]=cntr[i]-\frac{t}{n}sumr[i]sumr[i] 變成 r[i]r[i] 的前綴和,即sumr[i]=j=1ir[j]sumr[i]=\sum_{j=1}^ir[j]
最少步數爲 i=1nsumr[i]\sum_{i=1}^n\left|sumr[i]\right|
現在考慮環的情況。假設從 kk 位置之後斷開寫成一行,前綴和爲:
sumr[i]={sumr[i]sumr[k],i[k+1,n]sumr[i]+sumr[n]sumr[k],i[1,k]sumr[i]=\begin{cases}sumr[i]-sumr[k],i\in[k+1,n]\\sumr[i]+sumr[n]-sumr[k],i\in[1,k]\end{cases}
可以發現 sumr[n]=0sumr[n]=0 ,則答案爲 min1kn{i=1nsumr[i]sumr[k]}\min\limits_{1\leq k\leq n}\big\{\sum_{i=1}^n\left|sumr[i]-sumr[k]\right|\big\},顯然 s[k]s[k] 爲中位數時有最小值。
同理可得列的情況。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,t;
ll r[N],c[N],sumr[N],sumc[N],ansr,ansc;
int main()
{
	//freopen("tanabata.in","r",stdin);
	//freopen("tanabata.out","w",stdout);
	scanf("%d%d%d",&n,&m,&t);
	for(int i=1,x,y;i<=t;i++)
	    scanf("%d%d",&x,&y),r[x]++,c[y]++;
	if(t%n!=0&&t%m!=0)
		puts("impossible");
	else if(t%n==0&&t%m==0)
	{
		for(int i=1;i<=n;i++)
		    sumr[i]=sumr[i-1]+r[i]-t/n;
		for(int j=1;j<=m;j++)
		    sumc[j]=sumc[j-1]+c[j]-t/m;
		sort(sumr+1,sumr+n+1);
		sort(sumc+1,sumc+m+1);
		for(int i=1;i<=n;i++)
		    ansr+=abs(sumr[i]-sumr[n+1>>1]);
		for(int j=1;j<=m;j++)
		    ansc+=abs(sumc[j]-sumc[m+1>>1]);
		printf("both %lld\n",ansr+ansc);
	}
	else if(t%n==0)
	{
		for(int i=1;i<=n;i++)
		    sumr[i]=sumr[i-1]+r[i]-t/n;
		sort(sumr+1,sumr+n+1);
		for(int i=1;i<=n;i++)
		    ansr+=abs(sumr[i]-sumr[n+1>>1]);
		printf("row %lld\n",ansr);
	}
	else
	{
		for(int j=1;j<=m;j++)
		    sumc[j]=sumc[j-1]+c[j]-t/m;
		sort(sumc+1,sumc+m+1);
		for(int j=1;j<=m;j++)
		    ansc+=abs(sumc[j]-sumc[m+1>>1]);
		printf("column %lld\n",ansc);
	}
	return 0;
}

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述


在這裏插入圖片描述

#include<cstdio>
#include<cstring>
const int N=2050;
int k,n,num[N],vis[N];
bool dfs(int u,int pos)
{
	if(vis[u])return false;
	if(pos==n)return true;
	num[pos]=u&1;vis[u]=1;
	if(dfs((u<<1)&(n-1),pos+1))return true;
	if(dfs((u<<1|1)&(n-1),pos+1))return true;
	vis[u]=0;
	return false;
}
int main()
{
	while(~scanf("%d",&k))
	{
		n=1<<k;
		memset(vis,0,sizeof(vis));
		dfs(0,1);
		printf("%d ",n);
		for(int i=1;i<k;i++)
		    printf("0");
		for(int i=1;i<=n-k+1;i++)
		    printf("%d",num[i]);
		printf("\n");
	}
	return 0;
}

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述


在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef map<ll,int>type;
typedef type::const_iterator trc;
#define X first
#define Y second
int t;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
type divi(ll a)//唯一分解 
{
	type r;
	for(int i=2;(ll)i*i<=a;i++)
	    if(a%i==0)
	    {
	    	int p=0;
	    	while(a%i==0)++p,a/=i;
	    	r[i]=p;
		}
	if(a!=1)r[a]=1;
	return r;
}
ll euler(ll a,const type&r)//求歐拉函數phi 
{
	for(trc i=r.begin();i!=r.end();i++)
	    if(i->Y)a=a/i->X*(i->X-1);
	return a;
}
ll qmul(ll a,ll b,ll m)//快速乘,以免乘爆 
{
	ll ans=0,p=a%m;
	while(b)
	{
		if(b&1)ans=(ans+p)%m;
		p=(p+p)%m;
		b>>=1;
	}
	return ans;
}
ll qpow(ll a,ll b,ll m)//快速冪 
{
	ll ans=1,p=a%m;
	while(b)
	{
		if(b&1)ans=qmul(ans,p,m);
		p=qmul(p,p,m);
		b>>=1;
	}
	return ans;
}
int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d",&t);
	while(t--)
	{
		ll a,b,k;
		scanf("%lld%lld%lld",&a,&b,&k);
		ll g=gcd(a,b);a/=g,b/=g;
		type sb=divi(b),sk=divi(k);
		int p1=0;ll nb=b;//p1是轉化次數,即混循環之前的長度 
		for(trc i=sk.begin();i!=sk.end();i++)
		{
			int p=sb[i->X];sb[i->X]=0;
			p1=max(p1,(p+i->Y-1)/i->Y);
			while(p)nb/=i->X,p--;
		}
		ll p2;
		if(nb==1)p2=0;//是個有限小數 
		else
		{
			ll eb=euler(nb,sb);//φ(nb)
			p2=eb;//p2存k模b的階,初始化爲φ(nb) 
			sb=divi(eb);
			for(trc i=sb.begin();i!=sb.end();i++)
			{
				int p=i->Y;
				while(p)
				{
					if(qpow(k,p2/i->X,nb)==1)
					    p2/=i->X,p--;
					else break;
				}
				
			}
		}
		printf("%d %lld\n",p1,p2);
	}
	return 0;
}

賽後總結

感覺這套題有點難受……暴力也不太好打。T1排序中位數T2歐拉路T3數論,質量還是很高的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章