完全平方数的尾巴
思路:暴力枚举。
考虑。
所以当时又回到,即周期为。
所以我们只需要暴力枚举特判。
时间复杂度:
typedef long long ll; class Solution { public: /** * * @param x int整型 * @return bool布尔型 */ bool solve(int x) { for(int i=0;i<1000;i++) if(i*i%1000==x) return true; return false; } };
牛牛的字符串
思路:归并排序
此题的实质就是求序列的逆序对数,使得整个字符串呈非递增序列。
因为此题字符集只有。所以我们可以考虑用实现。
令表示前个集合中,字符的个数。
显然每次我们只需统计对取模后,比当前字符小的字符个数即可。
即:
时间复杂度:。
class Solution { public: int turn(string s, int k) { int n=s.size(),ans=0; vector<vector<int> >dp(k,vector<int>(26,0)); for(int i=0;i<n;i++){ for(int j=0;j<s[i]-'a';j++) ans+=dp[i%k][j]; dp[i%k][s[i]-'a']++; } return ans; } };
另外此题还可以用树状数组和线段树写,用权值树状数组维护一下前缀和即可。
时间复杂度:
#define lowbit(x) x&(-x) const int N=1e5+5; class Solution { public: int tr[N][30],sz=26; void upd(int p,int x,int k){ while(x<=26){ tr[p][x]+=k; x+=lowbit(x); } } int query(int p,int x){ int ans=0; while(x){ ans+=tr[p][x]; x-=lowbit(x); } return ans; } int turn(string s, int k) { memset(tr,0,sizeof tr); int n=s.size(); int ans=0; for(int i=0;i<n;i++){ int p=i%k; ans+=query(p,s[i]-'a'); upd(p,s[i]-'a'+1,1); } return ans; } };
下棋
思路:二维前缀和。
考虑:每次增加的贡献是多少,显然是一个类似于两个矩阵重合的图形。
对于当前点:,因为是在范围内。
对应矩阵的几个边界点:
所以该图形的贡献是:
所以我们只需要维护一下二维前缀和即可算出答案,需要注意的是边界情况。
时间复杂度:
const int N=2e3+10; typedef long long ll; class Solution { public: ll pre[N][N],a[N][N],mod=1e9+7; int d[4][2]={0,1,1,0,0,-1,-1,0}; struct P{ int x,y; }b[N*N]; ll cal(int n,int x1,int y1,int x2,int y2){ if(x1<1) x1=1;if(y1<1) y1=1; if(x2>n) x2=n;if(y2>n) y2=n; return pre[x2][y2]-pre[x2][y1-1]-pre[x1-1][y2]+pre[x1-1][y1-1]; } vector<int> getScores(int n, vector<int>& query) { int x=1,y=1,id=0; for(int i=1;i<=n*n;i++){ a[x][y]=i;b[i]={x,y}; int nx=x+d[id][0],ny=y+d[id][1]; if(a[nx][ny]||nx<1||nx>n||ny<1||ny>n) id=(id+1)%4; x+=d[id][0],y+=d[id][1]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j]; //printf("pre[%d][%d]=%d\n",i,j,pre[i][j]); } vector<int>ans; ll sum=0; int pos=1; for(int i=0;i<query.size();i++){ int step=query[i]; pos=(pos+step-1)%(n*n)+1; int x=b[pos].x,y=b[pos].y; sum+=cal(n,x-step+1,1,x+step-1,n)+cal(n,1,y-step+1,n,y+step-1); sum-=cal(n,x-step+1,y-step+1,x+step-1,y+step-1); sum%=mod; ans.push_back((int)sum); } return ans; } };