A. 求余来咯

思路:

暴力枚举每种情况,取最大值。

B. 乘法考验

思路:

乘积要求末尾有kk个零,也就是x10kx*10^k的形式(x末位不为零)(x末位不为零). aa所能提供的最大帮助为aa10k10^k的最大公因数。 因此输出10k/gcd(10k,a)10^k/gcd(10^k,a).

C. 回文树

思路:

用数组存储字符树,再用一个二维数组存储每个节点子树各个字母的数量,从下至上计算. 接着以此为基础,计算出初始的回文串数量. 对于每次修改,只会影响其子树,其父节点的子树,其父节点的父节点的子树...根节点的子树. 依次判断回文情况,本来回文现在不回文总数减一.本来不回文现在总数加一. 最后更新储存数组以便下一次计算.

D .构造题

思路:

nn个节点,则共有n(n1)/2n*(n-1)/2个正逆序对,则正序对有n(n1)/4n*(n-1)/4个,逆序对有n(n1)/4n*(n-1)/4个. 因逆序对有n(n1)/4n*(n-1)/4个,则从n1n-1开始,第ii个数nin-i会创造nin-i个逆序对(前面只有nn更大). 直到再放逆序对数量大于n(n1)n*(n-1)为止. 接着在这个地方放n减去剩余逆序对数量,这样逆序对数刚好为n(n1)/4n*(n-1)/4. 剩余地点依次放未放的数即可.

#include<bits/stdc++.h>
using namespace std;
long long n,a[100005],t,x;
int main(){
    freopen("gz.in", "r", stdin);
    freopen("gz.out", "w", stdout);
    cin>>n;
    x=n*(n-1)/4;
    for(int i=1;i<=n;i++){
        if(x>=n-i){
            a[i]=i;
            x=x-n+i;
        }
		else{
            a[i]=n-x;
            t=i+1;
            break; 
        }
    }
    for(int i=t,j=n;i<=n;i++,j--){
        if(j==n-x)j--;
        a[i]=j;
    }
    for(int i=1;i<=n;i++)cout<<a[i]<<" ";
}

0 条评论

目前还没有评论...