T1:寻找(find)
【题目描述】
你有一个长度为n个由abc三个字母组成的字符串s,你现在想知道有多少三元组(i,j,k)满足:
1、 s[i]=’a’,s[j]=’b’,s[k]=’c’
2、 j^2=ik
请你求出满足条件的三元组的数量
【输入描述】
第一行为n,表示字符串长度
第二行为一个长度为n的字符串。
【输出描述】
输出一个数, 表示满足条件的三元组的数量。
【样例】
输入 |
输出 |
5 abccc |
1 |
【数据范围】
对于30%的数据,
对于50%的数据,
对于70%的数据,
对于100%的数据,
solution:暴力只要判断j^2=i*kj是否为整数就行了,这里附上暴力代码
#include<cstdio> #include<iostream> #include<cmath> using namespace std; bool check(int m) { double n; n=sqrt(m); int k=(int)n; if(k*k==m) return true; else return false; } int main() { //freopen("find.in","r",stdin); //freopen("find.out","w",stdout); char c[5002]; int j,n,sum=0; scanf("%d",&n); scanf("%s",c+1); for(int i=1;i<=n;i++) for(int k=1;k<=n;k++) { if(check(i*k)) { j=sqrt(i*k); if(c[i]==‘a‘&&c[j]==‘b‘&&c[k]==‘c‘) //printf("%d %d %d\n",i,j,k); sum++; } } printf("%d\n",sum); }
T2:大芳的逆行板载(boat)
【题目描述】
大芳有一个不太好的习惯:在车里养青蛙。青蛙在一个n厘米(11n毫米s)的Van♂杆子上跳来跳去。她时常盯着青蛙看,以至于突然逆行不得不开始躲交叉弹。有一天他突发奇想,在杆子上每1厘米为一个单位,瞎涂上了墨水,并且使用mOgic,使青蛙跳过之处墨水浓度增加x。当然,他还会闲着无聊滴几滴墨水再涂♂抹均匀。
他现在无时无刻都想知道,第l厘米到第r厘米墨水的浓度是多少?
哦不!等等,他现在找到了一个计算器,可以输入几个数字与x,计算他们的x次幂和,所以……他想知道的是第l厘米到第r厘米墨水的浓度的x次幂和是多少?
大芳有3种舰长技能骚操作:
1、续:把青蛙放到第l厘米处,戳青蛙使其跳至r。效果:第l厘米至第r厘米墨水浓度增加x
2、抚♂摸:擦干杆子某一部分,重新滴加墨水并抹匀。效果:使第l厘米至第r厘米墨水浓度都变成x
最后一种是:
3、压线逆行,将车流看做⑨弹幕找安定点,掏出计算器,大喊板载后计算:
第l厘米至第r厘米墨水浓度的x次幂和是几何?记得答案要模1000000007
【输入描述】
第一行n和m,表示杆子长n厘米,大芳要进行m次骚操作。
第二行n个数字,表示初始墨水浓度。第i个数字为第i厘米墨水浓度
接下来每行4个数字,依次为:操作编号(1、2或3)l,r,x
【输出描述】
每次进行3操作,输出一行表示答案
记得膜模1000000007
【样例】
输入 |
输出 |
5 5 19844 14611 26475 4488 6967 2 1 3 15627 2 1 2 30113 2 3 5 14686 2 5 5 32623 3 1 2 8 |
466266421 |
【数据范围】
k表示询问的幂的大小,也就是操作3对应的x。
对于20%的数据,满足
对于另外20%的数据,满足
对于另外20%的数据,满足
对于另外20%的数据,满足
对于100%的数据,满足
操作1,2对应的
solution:模拟可以20分,正解是采用线段树。(20万岁( ̄▽ ̄)/)
#include <bits/stdc++.h> #define ll long long #define MOD 1000000007 using namespace std; int n,m,opt,A,B,C; int cnt[11][11]; struct node { ll v[11]; ll tagt,tagn; void init(int x) { v[0]=1; for (int i=1;i<=10;i++) v[i]=v[i-1]*x%MOD; } void add(int x) { int tv,r; for (int i=10;i>=0;i--) { tv=0,r=1; for (int j=i;j>=0;j--) { tv=(v[j]*cnt[i][j]%MOD*r+tv)%MOD; r=(ll)r*x%MOD; } v[i]=tv; } } }tr[400005]; inline int read() { int x=0;char ch=getchar(); while(ch<‘0‘||ch>‘9‘)ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x; } inline int DEC(int x) { return x>=MOD?x-MOD:x; } void pushup(int x) { int ls=x<<1,rs=x<<1|1; for (int i=0;i<=10;i++) tr[x].v[i]=DEC(tr[ls].v[i]+tr[rs].v[i]); } void downpush(int k,int l,int r) { int ls=k<<1,rs=k<<1|1,mid=(l+r)>>1; if (tr[k].tagt==1) { if (!tr[ls].tagt) tr[ls].tagt=1;if (!tr[rs].tagt) tr[rs].tagt=1; tr[ls].tagn+=tr[k].tagn,tr[rs].tagn+=tr[k].tagn; tr[ls].add(tr[k].tagn),tr[rs].add(tr[k].tagn); } else if (tr[k].tagt==2) { tr[ls].tagt=tr[rs].tagt=2; tr[ls].tagn=tr[rs].tagn=tr[k].tagn; tr[ls].init(tr[k].tagn);tr[rs].init(tr[k].tagn); for (int i=0;i<=10;i++) tr[ls].v[i]=tr[ls].v[i]*(mid-l+1)%MOD,tr[rs].v[i]=tr[rs].v[i]*(r-mid)%MOD; } tr[k].tagt=tr[k].tagn=0; } void build(int k,int l,int r) { if (l==r) { tr[k].init(read()); return; } int mid=(l+r)>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); pushup(k); } void update_add(int k,int l,int r,int a,int b,int x) { if (a<=l&&r<=b) { if (!tr[k].tagt) tr[k].tagt=1; tr[k].tagn+=x; tr[k].add(x); return; } if (tr[k].tagt) downpush(k,l,r); int mid=(l+r)>>1; if (a<=mid) update_add(k<<1,l,mid,a,b,x); if (mid<b) update_add(k<<1|1,mid+1,r,a,b,x); pushup(k); } void update_mod(int k,int l,int r,int a,int b,int x) { if (a<=l&&r<=b) { tr[k].tagt=2; tr[k].tagn=x; tr[k].init(x); for (int i=0;i<=10;i++) tr[k].v[i]=tr[k].v[i]*(r-l+1)%MOD; return; } if (tr[k].tagt) downpush(k,l,r); int mid=(l+r)>>1; if (a<=mid) update_mod(k<<1,l,mid,a,b,x); if (mid<b) update_mod(k<<1|1,mid+1,r,a,b,x); pushup(k); } int query(int k,int l,int r,int a,int b,int x) { if (r<a||l>b) return 0; if (a<=l&&r<=b) return tr[k].v[x]; if (tr[k].tagt) downpush(k,l,r); int mid=(l+r)>>1; return DEC(query(k<<1,l,mid,a,b,x)+query(k<<1|1,mid+1,r,a,b,x)); } int main() { freopen("boat.in","r",stdin); freopen("boat.out","w",stdout); cnt[0][0]=1; for (int i=1;i<=10;i++) { cnt[i][0]=1; for (int j=1;j<=i;j++) cnt[i][j]=cnt[i-1][j-1]+cnt[i-1][j]; } n=read(),m=read(); build(1,1,n); for (int i=1;i<=m;i++) { opt=read(),A=read(),B=read(),C=read(); switch (opt) { case 1: update_add(1,1,n,A,B,C); break; case 2: update_mod(1,1,n,A,B,C); break; case 3: printf("%d\n",query(1,1,n,A,B,C)); break; } } return 0; }
T3:消消乐(tet)
【题目描述】
有一个2n个数字排成一列,这个数列中由1..n中的数字组成,每个数字都恰好出现两次。每个回合可以交换相邻两个数字,交换以后如果有两个相同的数字相邻,那么将这两个数字消除,并将这两个数字的两端拼起来;如果拼接后的数列仍有相同的数字相邻,那么将引发连锁反应直到没有两个相同数字相邻。现在你想知道最少需要几个回合可以消除所有的数字。
【输入描述】
第一行输入一个n,表示数字范围。
接下来的2n行,每行一个数字,表示第i个位置的数字。
【输出描述】
第一行输出一个数,表示最少需要的回合数w。
接下来的w行,每行输出一个数m[i]。m[i]表示对于第i回合,你的操作为交换当前数列中的第m[i]个数和第(m[i]+1)个数。如果有多种方案,允许输出任意一种。
保证存在不超过的答案。
【样例】
输入 |
输出 |
5 5 2 3 1 4 1 4 3 5 2 |
2 5 2 |
【数据范围】
对于30%的数据,
对于100%的数据,
#include<cstdio> #define For( i , _Begin , _End ) for( int i = (_Begin) , i##END = (_End) ; i <= (i##END) ; i++ ) template< typename type >inline void swap( type &x , type &y ){ type t = x ; x = y ; y = t ; } template< typename type >inline void scanf( type &In ){ In = 0;char ch = getchar();type f = 1; for( ;ch> ‘9‘||ch< ‘0‘;ch = getchar() )if( ch == ‘-‘ ) f = -1; for( ;ch>=‘0‘&&ch<=‘9‘;ch = getchar() )In = In * 10 + ch - ‘0‘;In *= f; } static const int maxn = 5e4 + 10; static const int maxm = 1e6 + 10; int n,size,tp; int ans[maxm],pos[maxn],stk[maxm]; int main(){ freopen("tet.in","r",stdin); freopen("tet.out","w",stdout); scanf( n ) ; For( i , 1 , n << 1 ){ int x ; scanf( x ) ; stk[ ++tp ] = x; if( pos[x] ){ if( pos[x] == tp - 1 ){ tp -= 2 ; continue ; } int t = pos[x] ; while( t != tp - 1 ){ swap( stk[t] , stk[t + 1] ); pos[ stk[t] ]--; ans[ ++size ] = t++; } tp -= 2 ; pos[x] = 0 ; } else pos[x] = tp ; } printf("%d\n" , size ); For( i , 1 , size )printf("%d\n" , ans[i] ); return 0; }