zoukankan      html  css  js  c++  java
  • code+7正式赛划水记+HardA~C题解

    被同年级的吊锤了

    划水

    sometimes naive

    2:00看题,感觉不是很可做

    20分的时候有人切了T2,看了一下发现是sb题,20min切掉

    T1写了暴力找规律无果,交了10分上去

    去看T3,发现白给40分直接写

    150分以为稳了,还有1h的时候搞T1

    想到从后往前构造(?),因为决策点并不多并且主要时间在二分上所以是正解(暴论)

    打出了65,稍微调一下变成93

    这时还剩30min,大概是30多名

    然后看着排名飞速往后掉慌得一笔,去搞T3p质数的部分分搞不出来(并没有发现与模4有关)

    最后10min开始卡T1,45名

    最后5min掉出50名

    最后3min想到缩二分上下界,52名

    最后1min一Fa♂入魂,咸鱼翻身√

    A

    https://next.xuetangx.com/live/live20200523it002/live20200523it002/4071197/5468641

    k<=10^12

    题解是从前往后做的,设i以及i之后的操作次数为x,则最后一次一定是i,并且从后往前每i+1次中有一次i

    那么i被操作的次数为ceil(x/(i+1)),a则要加上第一次i前面的那一段,即a[i]=i-(x-1)%(i+1)

    然后把x剪掉ceil(x/(i+1)),往后做即可

    二分n,然后奇妙卡上下界

    也可以从后往前做,那就会遇到要决策0或i的地方,因为决策点不多所以可以过

    #pragma GCC optimize(2)
    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    #define file
    using namespace std;
    
    int i,j,k,l,r,mid,n,len,ss;
    ll a[10000001],K,s,sum;
    char st[20000001];
    
    ll pd(int n,ll s,ll sum,bool tp)
    {
    	int i,j,k,l,ss;
    	
    	fd(i,n,1)
    	{
    		ss=s%i;
    		if (!(ss)) {if (!tp) a[i]=0; else a[i]=i;}
    		else
    		a[i]=i-ss;
    		s+=(a[i]+s)/i;sum+=a[i];
    	}
    	
    	return sum;
    }
    void Write(int t)
    {
    	char a[10];
    	int i=0;
    	
    	if (!t) {st[++len]='0';st[++len]=' ';return;}
    	
    	while (t) a[++i]=t%10,t/=10;
    	while (i) st[++len]=a[i--]+'0';
    	st[++len]=' ';
    }
    
    int main()
    {
    	#ifdef file
    	freopen("a.in","r",stdin);
    	#endif
    	freopen("a.out","w",stdout);
    	
    	scanf("%lld",&K);
    	l=1;r=2000000;
    	if (K>100000000000ll)
    	l=floor(sqrt(K)*1.77244),r=floor(sqrt(K)*1.77255);
    	while (l<r)
    	{
    		mid=(l+r)/2;a[mid]=mid;
    		if (pd(mid-1,1,0,1)<K)
    		l=mid+1;
    		else
    		r=mid;
    	}
    	
    	n=l;a[n]=n;s=1;sum=n;
    	fd(i,n-1,1)
    	{
    		ss=s%i;
    		if (!(ss))
    		{
    			if (pd(i-1,s+s/i,sum-n,1)>=K)
    			a[i]=0;
    			else
    			a[i]=i;
    		}
    		else
    		a[i]=i-ss;
    		s+=(a[i]+s)/i;sum+=a[i];
    	}
    	
    	len=-1;
    	Write(n);st[++len]='
    ';
    	fo(i,1,n) Write(a[i]);st[++len]='
    ';
    	fwrite(st,1,len,stdout);
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    B

    直接求询问i的答案,把更新i所要的区间[ki+1,(k+1)i]挂在线段树上,如果操作1经过了区间就更新i的答案

    简单题

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define min(a,b) (a<b?a:b)
    #define low(x) ((x)&-(x))
    #define ll long long
    //#define file
    using namespace std;
    
    int b[100001],n,Q,i,j,k,l,tp,x,y,z;
    vector<int> tr[400001];
    ll Tr[100001],Tr2[100001];
    
    void Change(int t)
    {
    	while (t<=n) {++Tr[t]; t+=low(t);}
    }
    ll Find(int t)
    {
    	ll ans=0; while (t) {ans+=Tr[t];t-=low(t);};return ans;
    }
    void Change2(int t)
    {
    	while (t<=n) {++Tr2[t]; t+=low(t);}
    }
    ll Find2(int t)
    {
    	ll ans=0; while (t) {ans+=Tr2[t];t-=low(t);};return ans;
    }
    
    void change(int t,int l,int r,int x,int y,int s)
    {
    	int mid=(l+r)/2;
    	if (x>y) return;
    	
    	if (x<=l && r<=y) {tr[t].push_back(s);return;}
    	
    	if (x<=mid) change(t*2,l,mid,x,y,s);
    	if (mid<y) change(t*2+1,mid+1,r,x,y,s);
    }
    void find(int t,int l,int r,int x)
    {
    	int mid=(l+r)/2,tot=tr[t].size(),i,s;
    	
    	if (tot)
    	{
    		fo(i,0,tot-1)
    		{
    			s=tr[t][i];
    			if (((l-1)/s)<b[s]) continue;
    			
    			Change(s);++b[s];
    			while (b[s]*s<=n && Find2(min((b[s]+1)*s,n))-Find2(b[s]*s)) ++b[s],Change(s);
    			change(1,1,n,b[s]*s+1,min((b[s]+1)*s,n),s);
    		}
    		tr[t].clear();
    	}
    	if (l==r) return;
    	
    	if (x<=mid) find(t*2,l,mid,x);
    	else
    	find(t*2+1,mid+1,r,x);
    }
    
    int main()
    {
    	#ifdef file
    	freopen("b.in","r",stdin);
    	#endif
    	
    	scanf("%d%d",&n,&Q);
    	fo(i,1,n) change(1,1,n,1,i,i);
    	for (;Q;--Q)
    	{
    		scanf("%d",&tp);
    		if (tp==1)
    		{
    			scanf("%d",&x);
    			Change2(x);
    			find(1,1,n,x);
    		}
    		else
    		{
    			scanf("%d%d",&x,&y);
    			printf("%lld
    ",(Find(y)-Find(x-1))+(y-x+1));
    		}
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    C

    n<=10^5,p<=10^7

    40分直接枚举一个丢到桶里,然后把枚举另一个计算

    p是质数的时候答案长这样

    因为p没有平方因子,所以把p分解成Πpi后直接crt

    即求a^2+b^2=x%p等价于求a^2+b^2=x%pi方程组的解

    然后可以求出每个的解乘起来

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    //#define file
    using namespace std;
    
    int p[3163],T,n,i,j,k,l,P,x,len;
    bool f[3163];
    ll ans;
    
    void init()
    {
    	int i,j,k,l;
    	
    	fo(i,2,3162)
    	{
    		if (!f[i]) p[++len]=i;
    		fo(j,1,len)
    		if (i*p[j]<=3162)
    		{
    			f[i*p[j]]=1;
    			if (!(i%p[j])) break;
    		}
    		else
    		break;
    	}
    }
    
    int js(int p)
    {
    	if (p%4==1) {if (!(x%p)) return p*2-1;return p-1;}
    	if (p%4==3) {if (!(x%p)) return 1;return p+1;}
    }
    
    int main()
    {
    	#ifdef file
    	freopen("c.in","r",stdin);
    	freopen("c.out","w",stdout);
    	#endif
    	
    	init();
    	scanf("%d",&T);
    	for (;T;--T)
    	{
    		scanf("%d%d",&P,&x);ans=1;
    		
    		fo(i,1,len)
    		if (!(P%p[i]))
    		P/=p[i],ans*=js(p[i]);
    		if (P>1) ans*=js(P);
    		
    		printf("%lld
    ",ans);
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    磁盘io测试工具
    SqlServer性能瓶颈分析
    sqlserver镜像相关资料
    sqlserver数据库镜像运行模式
    Sqlserver2008 FileStream解决图片存储问题
    nginx负载均衡配置
    cacti-不出图形,cacti.log中出“ERROR: SQL Assoc Failed!
    Nginx的配置文件详解
    Linux环境(Centos) 安装mysql
    centos 命令行和图形桌面模式的切换
  • 原文地址:https://www.cnblogs.com/gmh77/p/12951279.html
Copyright © 2011-2022 走看看