zoukankan      html  css  js  c++  java
  • 【清北学堂周末刷题班】 Day5

    题目名称:大大大

      Illyasviel:"两个数乘起来会比一个数大吗?"

      Star-dust:"不知道啊,来算算吧。"

      读入一个(n),对于一个三元组((i,j,k))满足要求当且仅当(1leq i,j,kleq n)(i imes j geq k)

    输入描述:

      一行一个数字(n)

    输出描述:

      一行一个(ans)表示满足要求的三元组的个数。

    输入样例:

    10

    输出样例:

    900

    数据范围:

    对于30%的数据(nleq 100)

    对于60%的数据(nleq 5000)

    对于100%的数据(nleq 100000)

    对于30%的做法

    [思路]:n≤100,O(n³)即可满足需求,考虑分别枚举i,j,k并且判断这个是否满足要求

    #include<iostream>
    using namespace std;
    int main()
    {
    	int n;
    	long long ans;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    	for(int k=1;k<=n;k++)
    	if(i*j>=k)
    		ans++;
    	cout<<ans;
    }
    
    对于60%的做法

    [思路]:n≤5000,考虑对于一组确定的i,j,满足要求的k为min(n,k)。考虑枚举i,j在O(1)的时间内求一个可行区间。在O(n²)的时间里才能解决问题。

    复杂度是n/1+n/2+n/3--

    #include<iostream>
    using namespace std;
    int main()
    {
    	int n;
    	long long ans;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
    	if(i*j<=n)ans+=i*j;
    	else
    	{
    		ans+=n*(n-j+1);
    		break;
    	}
    	cout<<ans<<endl;
    }
    

    100分做法

    [思路]:n≤100000

    我们来反向考虑有多少个不满足要求的三元组,即i*j<k

    那么我们考虑将(i,j)插入i*j+1中,然后求一个前缀和即可。

    复杂度分析:i*j>n时可直接break。

    对于一个有对于一个i有

    [lfloorfrac{n}{i} floor ]

    个满足要求的j使得i*j<n总有效点对个数

    [sum{^n_{i=1}lfloorfrac{n}{i} floor} ]

    约等于

    [nsum{^n_{i=1}frac{1}{i}} ]

    #include<bits/stdc++.h>
    #define N 120000
    using namespace std;
    long long a[N];
    long long b[N];
    long long ans=0;
    long long n;
    int main(){
    	//freopen("1.in","r",stdin);
    	//freopen("1.out","w",stdout);
    	scanf("%lld",&n);
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n/i;j++){
    			a[j*i]++;
    		}
    	}
    	for(int i=1;i<=n;i++)b[i]=b[i-1]+a[i-1];
    	for(int i=1;i<=n;i++)ans+=b[i];
    	printf("%lld
    ",n*n*n-ans);
    }
    

    题目名称:kkk

      Star-dust:"你会最短路吗?"

      Illyasviel:"当然!"

      Star-dust:"那你来求一求这k个点中是否存在长度%P为L的路径吧。"

      Illyasviel:"这和最短路有什么关系吗?"

      Star-dust:"不知道啊~"

    输入描述:

    第一行一个数字$T$代表数据组数。
    
    对于每个数据,第一行三个数$n,m,k,P,L$表明有$n$个点,$m$条边,$k$个在图中的点。
    
    接下来一行k个数代表关键点。
    
    接下来$m$行每行三个数$x,y,z$表示$x$和$y$之间有一条长度为$z$的路径。
    

    输出描述:

    输出T行,当存在一条路径从起点和终点都在k个点中输出"YES",否则输出"NO"(不包含引号)。
    

    输入样例:

    1

    2 3 2 3

    1 2 1

    2 1 1

    输出样例:

    YES

    样例解释:

    1-2-1-2

    数据范围:

    对于40%的范围(Tleq 500,0leq L,zleq Pleq 20,kleq nleq mleq 500,kleq 10)

    对于80%的范围(Tleq 500,0leq L,zleq Pleq 20,kleq nleq mleq 500)

    对于100%的范围(Tleq 500,0leq L,zleq Pleq 10^9,kleq nleq mleq 500),(P)是奇数。

    100分做法

    #include<bits/stdc++.h>
    using namespace std;
    int gcd(int x,int y){
    /*	if(y==0){
    		y++,y--;
    		return 0;
    	}*/
    	if(x%y==0)return y;
    	return gcd(y,x%y);
    }
    int solve(){
    	int n,m,k,P,L;
    	scanf("%d%d%d%d%d",&n,&m,&k,&P,&L);
    	for(int i=1;i<=k;i++){
    		int x;
    		scanf("%d",&x);
    	}
    	if(L==0)L=P;
    	int A=P,B=P;
    	for(int i=1;i<=m;i++){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		if(z==0){
    			z=P;
    		}
    		A=gcd(A,z);
    	}
    	B=gcd(B,L);
    	if(B%A==0)printf("YES
    ");
    	else printf("NO
    ");
    }
    int main(){
    	int T;
    	freopen("kkk10.in","r",stdin);
    	freopen("kkk10.out","w",stdout);
    	scanf("%d",&T);
    	while(T--)solve();
    }
    

    题目名称:A的B次方

    题目描述:

      Illyasviel:"今天我们学了(A^B)?"

      Star-dust:"我们也学了诶!"

      Star-dust:"那我来考考你吧!"

      已知A和P,求一个任意的B使得(A^B≡B^A(mod P))

    输入描述

      一行输入两个整数(A)(P)

    输出描述

      输出任意一个满足要求的数字(B)

      (B)要为一个不大于(10^{18})的正整数。

    样例输入

    78 100

    样例输出

    16

    数据范围

    对于30%的数据:

    (1leq A,Pleq 1000)

    对于30%的数据:

    (P)为质数

    对于100%的数据:

    (64leq Aleq 10^9)

    (Pleq 10^9)

    (1leq Bleq10^{18})

    #include<bits/stdc++.h>
    using namespace std;
    long long A,P;
    long long phi(long long x){
    	long long ans=1;
    	for(long long i=2;i*i<=x;i++){
    		if(x%i==0)ans*=(i-1),x/=i;
    		while(x%i==0)x/=i,ans*=i;
    	}
    	return ans*max(x-1,1LL);
    }
    long long power(long long x,long long k,long long P){
    	long long ans=1;
    	x%=P;
    	while(k){
    		if(k&1)(ans*=x)%=P;
    		(x*=x)%=P;
    		k>>=1;
    	}
    	return ans;
    }
    int main(){
    	scanf("%lld%lld",&A,&P);
    	long long B=A+P*phi(P);
    	printf("%lld
    ",B);
    	return 0;
    //	scanf("%lld
    ",&P);
    //	printf("%lld %lld
    ",P,phi(P));
    //	return 0;
    	printf("%lld %lld
    ",power(A,B,P),power(B,A,P));
    } 
    

    题目名称:灯塔

      Star-dust:"每个人都是灯塔,灯塔之间相隔万里,无法触碰无法沟通,唯一能做的就是用自己的光去照耀别人。"

      Illyasviel:"如果能被某个灯塔一直照耀,那一定很幸福吧。"

      Star-dust:"我能成为你的灯塔吗?"

      Illyasviel:"好啊~"

      海上有着(n)个灯塔,第(i)个灯塔在位置(i)闪耀着,灯塔的光覆盖着([i-d_i,i+d_i])的所有灯塔,对于第(k)个灯塔,他想知道有多少个(i)满足(i<k)且至少存在一个在(i)(k)中间的灯塔(j)满足灯塔(j)同时被灯塔(i)和灯塔(k)照耀,并且(j)(k)的距离小于等于(j)(i)之间的距离。

    输入描述:

      第一行一个整数(n)

      接下来一行(n)个数字,第(i)个代表(d_i)

    输出描述:

      一行一个答案(ans)

      (f_k)表示对于第(k)个灯塔有多少个灯塔满足条件。

      (ans)为n个(f_k)的异或和。

    样例输入:

    10
    2 2 3 2 3 2 3 3 3 1

    样例输出:

    2

    样例解释:

    对应位置答案分别为0 0 1 2 3 3 3 4 4 2

    数据范围:

    对于20%的数据:(nleq 100)

    对于20%的数据:(nleq5000)

    对于20%的数据:(di)完全相同

    对于20%的数据:(nleq 100000)

    对于100%的数据:(nleq 3000000),(1 leq d_ileq n)

    #include<bits/stdc++.h>
    #define N 3200000
    #define lowbit(x) ((x)&-(x))
    using namespace std;
    int n,d[N],f[N];
    int ans;
    vector<int>a[N];
    int t[N]; 
    namespace bit{
    	int t[N];
    	int insert(int x,int a){
    		x=n-x+1;
    		for(int i=x;i<=n;i+=lowbit(i))t[i]+=a;
    		return 0;
    	}
    	int query(int x){
    		x=n-x+1;
    		int ans=0;
    		for(int i=x;i;i-=lowbit(i))ans+=t[i];
    		return ans;
    	}
    }
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    };
    int main(){
    	//freopen("beacon.in","r",stdin);
    	//freopen("beacon.out","w",stdout);
    	n=read();
    	for(int i=1;i<=n;i++)d[i]=read();
    	for(int k=3;k<=n;k++){
    		int i=k-2;
    		int j=i+d[i];
    		int l=2*j-i+1;
    		l=min(l,n+1);
    		a[l].push_back(j);
    		bit::insert(min(j,n),1);
    		for(int o=0;o<a[k].size();o++){
    			bit::insert(min(a[k][o],n),-1);
    		}
    		f[k]=bit::query(max(k-d[k],1));
    	}
    //	for(int i=1;i<=n;i++)printf("%d ",f[i]);
    //	printf("
    ");
    //	return 0;
    	for(int i=1;i<=n;i++)ans^=f[i];
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    Android 在一个程序中启动另一个程序
    Android SDK Manager国内无法更新的解决方案
    Android studio 安装中遇到一些问题的解决办法,分享一下
    apache服务器伪静态配置说明
    POJ3253 Fence Repair【贪心】
    洛谷P1090 合并果子【贪心】
    POJ3069 Saruman's Army【贪心】
    洛谷P1012 拼数【字符串+排序】
    POJ3617 Best Cow Line【贪心】
    洛谷P1583 魔法照片【模拟+排序】
  • 原文地址:https://www.cnblogs.com/royann/p/13912483.html
Copyright © 2011-2022 走看看