C - Monoblock,I-Yet Another FFT Problem

90 阅读2分钟

C - Monoblock

昨天想的结论想的太复杂了,没有看出真正的规律来,应该左右分别讨论,如果x和a[i-1]相同那么只有与i,i-1在一块的区间才会受到影响,多算几个就会发现是(n-i+1)*(i-1),总答案就要加上这个数,如果是情况相反的话总答案就要减去这个数,而i+1的话就是加的数变成了(n-i)*i别的和左边一样,一开始的情况如果a[i]==a[i-1]那么受影响的只有i这一个数后缀也就只有i做第一个时才会增加一个,所以后缀+1,答案+=后缀,如果a[i]!=a[i-1]那么受影响的是i以及i前边的数,所以后缀要加i,答案+=后缀

Codeforces Round #816 (Div. 2) A - D - 知乎 (zhihu.com)

ll n,m,a[100005];
int main(){
    scanf("%lld%lld",&n,&m);
    ll suf=0,ans=0;
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        if(a[i]!=a[i-1]) suf+=i,ans+=suf;
        else suf++,ans+=suf;
    }
    while(m--){
        ll i,x;
        scanf("%lld%lld",&i,&x);
        if(a[i]==x){
            printf("%lld\n",ans);continue;
        }
        if(a[i-1]==x&&a[i]!=a[i-1]) ans-=(n-i+1)*(i-1);
        if(a[i-1]!=x&&a[i]==a[i-1]) ans+=(n-i+1)*(i-1);
        if(a[i+1]==x&&a[i]!=a[i+1]) ans-=(n-i)*i;
        if(a[i+1]!=x&&a[i]==a[i+1]) ans+=(n-i)*i;
        printf("%lld\n",ans);
        a[i]=x;
    }
    return 0;
}

[I-Yet Another FFT Problem?_"蔚来杯"2022牛客暑期多校训练营10 (nowcoder.com) 鸽笼原理

把式子变换一下也就是a[i]+b[l]==a[j]+b[k],那也就是a[i]+b[j]只要出现了两次就说明是有重复的数了,当然前提是在去重的情况下,所以我们可以直接n*m的暴力,因为a[i],b[i]的范围都在1e7以内,所以a[i]+b[j]也就在2e7以内,所以只要跑上2e7+2次就一定会有一个数出现两次的情况,所以这也不算暴力,当然也会出现a中有两个数相等,b中也有两个数相等的情况,那就特判一下就可以了,然后代码上又被折磨了,一直不过,最后改的都快一模一样了说内存超限,然后换了个标准内存又可以了,真是服了,,然后自己写的代码不行,别人的就能过,应该是scanf的原因,,

int n,m;
bool mp[20000007];
pair<int,int>vis[20000007];
int a[1000006],b[1000006],id[10000007],posa[10000007],posb[10000007],ai=0,aj=0,bi=0,bj=0;
int main(){
    cin >> n >> m;
    for (int i = 1; i <= n; i++)cin >> a[i], posa[a[i]] = i;
    for (int i = 1; i <= m; i++)cin >> b[i], posb[b[i]] = i;
    for (int i = 1; i <= n; i++) {
        if (id[a[i]]) { ai = id[a[i]], aj = i; break;}
        id[a[i]] = i;
    }
    memset(id,0,sizeof(id));//清空
    for (int i = 1; i <= m; i++) {
        if (id[b[i]]) {bi = id[b[i]], bj = i; break;}
        id[b[i]] = i;
    }
    if (ai != 0 && aj != 0 && bi != 0 && bj != 0) {
        cout << ai << " " << aj << " " << bi << " " << bj << endl;
        return 0;
    }
sort(a + 1, a + 1 + n); n = unique(a + 1, a + 1 + n) - (a + 1);
    sort(b + 1, b + 1 + m); m = unique(b + 1, b + 1 + m) - (b + 1);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            int num = a[i] + b[j];
            if (mp[num]) {
                int ai = vis[num].first, bj = vis[num].second;
                cout << ai << " " << posa[a[i]] << " " << bj << " " << posb[b[j]] << endl;
                return 0;
            }
            else {
                mp[num] = 1;
                vis[num] = { posa[a[i]],posb[b[j]] };
            }
        }
    }
    cout << "-1" << endl;
    return 0;
}