A Ternary String
上图中的最后两行的最后面的%c 应该是大写的 不应该是在指数上%c
而且 在递归过程中 b是永远小于phi的
而且因为-3的存在,会出现返回负数的情况,所以取模的时候要加上一个模数的5倍 。。6 7 8 9 10...倍都可以。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char s[100005];
ll qpow(ll a, ll b, ll mod) {
ll ret = 1;
while(b) {
if(b & 1) ret = (ret * a) % mod;
a = (a * a) % mod; b >>= 1;
}
return ret;
}
map<ll,ll> mp;
ll phi(ll k)
{
ll i,s=k,x=k;
if (mp.count(k)) return mp[x]; //记忆化存储
for(i = 2;i * i <= k; i++)
{
if(k % i == 0) s = s / i * (i - 1);
while(k % i == 0) k /= i;
}
if(k > 1) s = s / k * (k - 1);
mp[x]=s; return s;
}
ll dfs(int x, ll mod) {
if(x == 0 || mod == 1) return 0;
if(s[x] == '2') {
ll tmp = (qpow(2, (dfs(x - 1, phi(mod)) + phi(mod)) % phi(mod), mod) * 6LL % mod - 3LL + mod) % mod;
//cout << mod << " " << tmp << endl << endl;;
return tmp;
}
if(s[x] == '0') {
return (dfs(x - 1, mod) + 1LL + mod) % mod;
}
if(s[x] == '1') {
return (2LL * dfs(x - 1, mod) % mod + 2LL + mod) % mod;
}
return 0;
}
int t;
int main() {
scanf("%d", &t);
while(t--) {
scanf("%s", s + 1);
printf("%lld\n", dfs(strlen(s + 1), 1e9+7));
}
return 0;
}
D Another Distinct Value
构造 找规律 一个正方形 ,以右上到左下的对角线为分界,左上全为1右下全为-1 ,这条对角线左下一半全为1,右上一半全为0
#include<bits/stdc++.h>
using namespace std;
int ma[222][222];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
if(n%2==1)
{
cout<<"impossible"<<endl;
}
else{
for(int i=1;i<=n-1;i++)
{
for(int j=1;j<=n-i;j++)
{
ma[i][j]=1;
ma[n-j+1][n-i+1]=-1;
}
}
for(int i=1;i<=n/2;i++)
{
ma[i][n-i+1]=0;
}
for(int i=n/2+1;i<=n;i++)
{
ma[i][n-i+1]=1;
}
printf("possible\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j>1)printf(" ");
printf("%d",ma[i][j]);
}
printf("\n");
}
}
}
return 0;
}
G Maximum Mode
给一串数列,给m次去除一个数的操作,求用掉m次操作后的众数最大是多少。
我们将每个数出现的次数记录,然后按照出现的次数排序,次数相同,大的在后面,然后遍历每一个数都为众数,看看能不能让这个数为众数,取最大即可。
验证能不能成为众数,我们只要统计数量多于该数的数的数量总和,然后减成该数数量-1 ,再与m比一下即可。
#include<bits/stdc++.h>
using namespace std;
struct node{
int da;
int sl;
}p[111111];
int sll[111111];
int hz[111111];
map<int ,int >pp;
bool cp(node x,node y)
{
if(x.sl!=y.sl)return x.sl<y.sl;
return x.da<y.da;
}
int main()
{
int t;
cin>>t;
while(t--)
{
pp.clear();
int n,m;
scanf("%d%d",&n,&m);
int lss;
int js=1;
for(int i=0;i<n;i++)
{
scanf("%d",&lss);
if(pp[lss]==0)
{
pp[lss]=js;
p[js].da=lss;
p[js].sl=1;
js++;
}
else
{
p[pp[lss]].sl++;
}
}
sort(p+1,p+js,cp);
js--;
for(int i=1;i<=js;i++)
sll[i]=p[i].sl;
int ans=-1;
hz[js]=p[js].sl;
for(int i=js-1;i>=1;i--)
hz[i]=hz[i+1]+p[i].sl;
for(int i=js;i>=1;i--)
{
if(p[i].da<ans)
continue;
int it=lower_bound(sll+1,sll+js+1,p[i].sl)-sll;
int sum;
if(it>i)
{
sum=hz[it]-(p[i].sl-1)*(js-it+1);
}
else sum=(hz[it]-p[i].sl)-(p[i].sl-1)*(js-it);
if(sum<=m)
{
ans=max(ans,p[i].da);
}
}
printf("%d\n",ans);
}
return 0;
}
F Beautiful Garden
在一个矩形里建矩形水池,然后让整张图对称。
只要找一下长度和宽度最大的不对称地方,这作为建水池的大小下限,再算一下就可以了。
#include<bits/stdc++.h>
using namespace std;
char ma[2222][2222];
int main()
{
int n,m;
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=0;i<n;i++)
scanf("%s",&ma[i]);
int p=0;
int q=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(ma[i][j]!=ma[i][m-1-j])
{
q=max(q,abs(j-(m-1-j))+1);
}
if(ma[i][j]!=ma[n-1-i][j])
{
p=max(abs(n-1-i-i)+1,p);
}
}
}
if(p==0)p=2;
if(q==0)q=2;
int ans=(n-p)/2;
ans=ans*((m-q)/2);
if(ans<0)ans=0;
cout<<ans<<endl;
}
return 0;
}