The Preliminary Contest for ICPC Asia Nanjing 2019【 B F】

B

传送门
在这里插入图片描述
题意:
给定a,b;让求X=(a^( a^a) ^a…)a的b次幂,其实就是欧拉降幂的递归形式,注意b==0输出(1modm)

代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<cmath>
#define Xiaobo main
#define IO cin.tie(0),cout.tie(0),ios::sync_with_stdio(false);
using namespace std;
const int maxn=1e6+7;
const int mod=1e9+7;
const double eps=1e-15;
const double pi=acos(-1);
const int INF=0x3f3f3f;
typedef long long ll;
ll read(){ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();if(c == '-')Nig = -1,c = getchar();while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();return Nig*x;}
ll qpow(ll a,ll b,ll m){ ll ans=1; while(b){ if(b&1) ans=ans%a%m;a=a*a%m,b>>=1;} return ans; }
ll qpow(ll a,ll b){ ll ans=1;while(b>0){ if(b&1) ans=ans*a;a*=a,b>>=1; } return ans;}
ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b);}
ll mul(ll a,ll b,ll m){ll res=0;while(b>0) { if(b&1) res=(res+a)%m;a=(a+a)%m;b>>=1;}return res;}
int lowbit(int x) { return x&(-x); }
ll num[maxn];
int prim[maxn];
int phi[maxn],cnt;
bool vis[maxn];
ll a,b,p;
ll Eular() {//求欧拉函数
	phi[1]=1;
	for(int i=2;i<maxn;i++ ){
		if(!vis[i]) {
			prim[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;i*prim[j]<maxn&&j<=cnt;j++) {
			vis[i*prim[j]]=1;
			if(i%prim[j]) phi[i*prim[j]]=phi[i]*(prim[j]-1);
			else {
				phi[i*prim[j]]=phi[i]*prim[j];
				break;
			}
		}
	}
}
ll Pow(ll a,ll b,ll c) {
	ll ans=1;
	a=a<c?a:a%c+c;
	while(b) {
		if(b&1) ans=ans*a<c?ans*a:ans*a%c+c;
		a=a*a<c?a*a:a*a%c+c; 
		b>>=1;
	}
	return ans<c?ans:ans%c+c;
}
ll Fun(ll cur,ll p) {
	if(!cur||p==1) return a<p?a:a%p+p;
	return Pow(a,Fun(cur-1,1LL*phi[p]),p);
}
int Xiaobo()
{
	IO;
	Eular();
	int t;
	t=read();
	while(t--) {
		scanf("%lld%lld%lld",&a,&b,&p);
		if(!b) printf("%d\n",1%p);
		else printf("%lld\n",Fun(b-1,p)%p);
	}
	return 0;
}

F

传送门
在这里插入图片描述
不得不得说这道题题意真难理解…卡了好久才懂看来以后英语要提高了…
题意
首先说下这个s序列需要满足的条件
1.Si[1]=i 每个位置的Si[ ]第一个数等于它本身;
2.Si是递减数列
3.Si[ ] 中的元素是给定数组中的数对应的下标 注意j到i在原数组中的下标之间差值不能大于K
4.如果Si的长度不够n那么补0 没意义不用管
5.要保证Si[ ]尽可能的大
样例解释
2
3 1
3 2 1
7 2
3 1 4 6 2 5 7
这里只解释第二组
我们记录下原数组中的下标
1 2
2 5
3 1
4 3
5 6
6 4
7 7
然后k等于2
对于s1[]只有1一个数 因为不可能再递减了
对于S2[]可以有1 2 两个数 我们要判断下2和1在数组中的下标的差值即为3>k所以1不符合规则还是只有一个
对于S3[]可以有1 2 3 三个数 而3与2下标差4不符合 3与1下标差1 所以有1 3 两个数
向后同理 可以用递推去写,当前数字等于和比它小的最符合题意的数字的值+1 算是动态规划吧0.0
但是这种做法最坏复杂度N^2 我们比赛时只是抱着试试的态度结果A了 … 可惜还是太弱了 加油吧

代码

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int num[100005]={0};
		int index[100005]={0};
		int dp[100005]={0,1};
		int n,k;
		scanf("%d %d",&n,&k);
		for(int i=1;i<=n;i++)
		{
		   scanf("%d",&num[i]);
		   index[num[i]]=i;
	    }
	    sort(num+1,num+1+n);
	    for(int i=2;i<=n;i++)
	    {
	    	dp[i]=1;
	    	for(int j=i-1;j>=1;j--)
	    	{
	    		if(abs(index[num[i]]-index[num[j]])<=k)
	    		{
	    			dp[i]+=dp[j];
	    			break;
				}
			}
		}
		for(int i=1;i<=n;i++)
		{
			if(i==1) printf("%d",dp[i]);
			else printf(" %d",dp[i]);
		}
		printf("\n");
	}
	return 0;
}

PS

南京网络赛就这样过去了,一次比一次菜了,我们队写B题的时候都推出解题方法了,可惜我对欧拉函数了解太少,记得好久之前用过欧拉降幂,奈何关键时候忘记了,一直卡C,最后才发现C题需要化简下成多项式乘法 然后套用NTT求解 还是不会 我还是先把FFT学会吧 其实最后真该和队友一起看B的 啊啊啊 好亏的一道题,听大佬说这是一道原题的变形,呜呜呜 好像原题写过,,,,更难受了 。遥遥补题路,希望今年能通过一场网络赛进入现场赛,加油吧!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值