题目思路

这题我只能说想了没多久就想出来了,一开始看到这个题目的时候下意识想要用数组分组然后再合并的一个做法,但是想了一想那样时间复杂度好像有点高来着,这题应该有一些更优的做法,然后就在纸上自己捣鼓了一下,发现这个问题其实用循环链表就能很好的去解决了,时间复杂度也能到 O(qi) 的程度。

首先就是他会把前 i 个元素做加法或者乘法,这个就不多说了,这题的重点在如何让做过操作的元素移动到列表的最后,我们可以注意到,他这个移动其实只是单纯的把第一个元素移动到最后一个元素,那我们就可以把这个列表看成是一个环,然后每次做完操作之后都把链表的头指针往后移,因为是闭环的关系,所以就能一直重复下去了。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
 
#define ll long long int
 
using namespace std;
 
class Node{
public:
    ll value;
    Node *next;
     
    Node(ll n) : value(n) {} 
};
 
int main() {
    ll n, tmp;
    Node *head = new Node(0), *p = head;
    cin>>n;
    for(ll i = 0; i < n; i++) {
        cin>>tmp;
        p->next = new Node(tmp);
        p = p->next;
    }
    p->next = head->next;
    head = head->next;
    p = head;
    ll q, m, op, val;
    m = n;
    cin>>q;
    for(ll i = 0; i < q; i++) {
        cin>>n>>op>>val;
        switch (op) {
            case 1:
                for(ll i = 0; i < n; i++) {
                    p->value = p->value + val;
                    p->value %= 1000000007;
                    p = p->next;
                }
                break;
            case 2:
                for(ll i = 0; i < n; i++) {
                    p->value = p->value * val;
                    p->value %= 1000000007;
                    p = p->next;
                }
                break;
        }
    } 
    for(ll i = 0; i < m; i++) {
        printf("%lld ", p->value);
        p = p->next; 
    }
    return 0;
}