2 条题解

  • 6
    @ 2023-10-28 13:30:04

    方法比较拙劣,大佬不喜勿喷

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int MAXN = 1e5;
    const int MOD = 10007;
    ll n, m, sum[MAXN + 5][2], a[MAXN + 5][2], color[MAXN + 5], num[MAXN + 5], ans;
    int main()
    {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            cin >> num[i];
            num[i] %= MOD;
        }
        for (int i = 1; i <= n; i++)
        {
            cin >> color[i];
            ll c = color[i];
            ll g = i % 2;
            a[c][g]++;
            sum[c][g] += num[i];
            sum[c][g] %= MOD;
        }
        for (int i = 1; i <= n; i++)
        {
            ll c = color[i];
            ll g = i % 2;
            ans += i % MOD * ((sum[c][g] + (a[c][g] - 2) % MOD * num[i] + MOD) % MOD);
            ans %= MOD;
        }
        cout << ans << endl;
        return 0;
    }
    
    • 5
      @ 2022-4-29 15:29:03

      这道题和那个中间的y其实没有任何关系

      首先对条件1变形,得到2y=x+z2y=x+z,因此x和z要么都是奇数要么都是偶数。

      那我们可以进行分组,将奇数相同的颜色放一组,偶数相同的颜色放一组。

      color[i]color[i]为每个的颜色,number[i]number[i]为自己的数字。

      a[color[i]][a[color[i]][i%2]]统计个数

      那么在一个组里面,实际就是排列组合的选法,每次选2个不同的。

      设一个组里有k个,

      用数组y1,y2,,yky1,y2,……,yk 代替下标,x1,x2,xkx1,x2……,xk 那么分数就是

      (y1+y2)(x[1]+x[2])+(y1+y3)(x[1]+x[3])++(y1+yk)(x[1]+x[k])+(y2+y3)(x[2]+x[3])+(y2+y4)(x[2]+x[4])++(y2+yk)(x[2]+x[k])+(yk1+yk)(x[k1]+x[k])(y1+y2)*(x[1]+x[2])+(y1+y3)*(x[1]+x[3])+……+(y1+yk)*(x[1]+x[k]) + (y2+y3)*(x[2]+x[3])+(y2+y4)*(x[2]+x[4])+……+(y2+yk)*(x[2]+x[k]) +(y_{k-1}+yk)*(x[k-1]+x[k])

      化简可以得到

      y1(x[1]+x[2]+x[1]+x[3]++x[1]+x[k])+y1*(x[1]+x[2]+x[1]+x[3]+……+x[1]+x[k])+

      y2(x[1]+x[2]+x[2]+x[3]++x[2]+x[k])++y2*(x[1]+x[2]+x[2]+x[3]+……+x[2]+x[k])+……+

      yk(x[1]+x[k]+x[2]+x[k]++x[k1]+x[k])yk*(x[1]+x[k]+x[2]+x[k]+……+x[k-1]+x[k])

      ==

      y1(x[1](k2)+x1+x2++xk)+y1*(x[1]*(k-2)+x1+x2+……+xk)+

      y2(x[2](k2)+x1+x2++xk)++y2*(x[2]*(k-2)+x1+x2+……+xk)+……+

      yk(x[k](k2)+x1+x2++xk)yk*(x[k]*(k-2)+x1+x2+……+xk)

      预处理前缀和x1+x2++xkx1+x2+……+xk就可o(n)求出来

      输入颜色的时候如果下标i是奇数,那么就是a[color[i]][1]++a[color[i]][1]++,颜色color[i]color[i]分到奇数组

      的个数加1,其余同理。提前求和就是

      sum[color[i]][1]=sum[color[i]][1]+number[i]sum[color[i]][1]=sum[color[i]][1]+number[i]

      最终针对下标为i的它能选出的组合的和就是

      i(a[color[i]][i*(a[color[i]][i%2]]-2)number[i]+sum[color[i]][)*number[i]+sum[color[i]][i%2]]

      i就对应刚才公式里的y

      #include <bits/stdc++.h>
      using namespace std;
      const int mod=10007;
      long long n,m,number[100005],color[100005],a[100005][2],sum[100005][2],ans;
      int main()
      {
      	ios::sync_with_stdio(false);
      	cin.tie(0);
      	cin>>n>>m;
      	for(int i=1;i<=n;i++)
      	{
      		cin>>number[i];
      	}
      	for(int i=1;i<=n;i++)
      	{
      		cin>>color[i];
      		if(i%2==0)
      		{
      			a[color[i]][0]++;//统计下标为i的color[i]这个颜色个数
      			sum[color[i]][0]=(sum[color[i]][0]+number[i])%mod;//求这个颜色所有的和保存进去
      		}
      		else
      		{
      			a[color[i]][1]++;
      			sum[color[i]][1]=(sum[color[i]][1]+number[i])%mod;//求这个颜色所有的和保存进去
      	}
      	for(int i=1;i<=n;i++)
      	{
      		ans=(ans+i*((a[color[i]][i%2]-2)*number[i]%mod+sum[color[i]][i%2]))%mod;
      		////a[color][i%2]就是这一组的个数然后减去2,乘以number[i]再加上number[i]的前缀和。整体乘以的i,就是下标。
      	}
      	cout<<ans;
      	return 0;
      }
      

      • @ 2023-8-2 16:51:43

        else少了}

        
        
        #include <bits/stdc++.h>
        using namespace std;
        const int mod=10007;
        long long n,m,number[100005],color[100005],a[100005][2],sum[100005][2],ans;
        int main()
        {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>m;
        for(int i=1;i<=n;i++)
        {
        cin>>number[i];
        }
        for(int i=1;i<=n;i++)
        {
        cin>>color[i];
        if(i%2==0)
        {
        a[color[i]][0]++;//统计下标为i的color[i]这个颜色个数
        sum[color[i]][0]=(sum[color[i]][0]+number[i])%mod;//求这个颜色所有的和保存进去
        }
        else
        {
        a[color[i]][1]++;
        sum[color[i]][1]=(sum[color[i]][1]+number[i])%mod;//求这个颜色所有的和保存进去
        }
        }
        for(int i=1;i<=n;i++)
        {
        ans=(ans+i*((a[color[i]][i%2]-2)*number[i]%mod+sum[color[i]][i%2]))%mod;
        ////a[color][i%2]就是这一组的个数然后减去2,乘以number[i]再加上number[i]的前缀和。整体乘以的i,就是下标。
        }
        cout<<ans;
        return 0;
        }
        
        
        
        
    • 1

    信息

    ID
    1406
    时间
    1000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    156
    已通过
    75
    上传者