C - Spiral Rotation

赛时未做出,并浪费了大量时间一错再错。
关键词:变换周期
启发:
图+位置变换一定要动手画图,并模拟一下,不难发现会有周期。

E - 3 Team Division

要点:1.注意关注数据范围 2.学会经典时间优化技巧
2中提及到的经典技巧:知道n个元素的结合S,那么可以通过枚举n-1个元素,用S减少n-1的集合,求的最后一个元素。

F - Road Blocked

注意到:N <= 300
顺序操作是减边
逆转操作就是加边
更新减边的最短路或许很难,但是更新加边的最短路或许简单。
设置 $dp_{k,x,y}$ 表示只考虑前 $k$ 条边 从 $x-&gt;y$ 的最短距离,那么转移情况就是是否使用第k条边,时间为 $O(1)$。
对于新加1条边,更新全部状态的时间就是 $O(N * N)$
假设加T条边,时间就是 O(K * N * N)
对于未删除的边可以Floyd $O(N^3)$ 预处理
逆序操作中途中不断记录答案即可,记得逆转输出

const int N = 300 + 10, M = N * N;

struct Edge{
    ll u, v, w;
}e[M];

int n, m, q;
int ty[M]; //道路是否被删除

ll f[N][N];

void solve(){
    cin >> n >> m >> q;
    for (int i = 1; i <= m; i ++ ){
        int u, v, w;
        cin >> u >> v >> w;
        e[i] = {u, v, w};
    }
    vector<tuple<int, int, int>> vq;
    for (int i = 1; i <= q; i ++ ){
        int c;
        cin >> c;
        if (c == 1){
            int cx;
            cin >> cx;
            ty[cx] = 1;//删除
            vq.push_back(make_tuple(c, cx, 0));
        }else{
            int u, v;
            cin >> u >> v;
            vq.push_back(make_tuple(c, u, v));
        }
    }
    //floyd -初始化
    for (int i = 1; i <= n; i ++ ) 
        for (int j = 1; j <= n; j ++ )
            f[i][j] = i == j ? 0 : 1e18;
    for (int i = 1; i <= m; i ++ )
        if (ty[i] == 0){
            auto [u, v, w] = e[i];
            f[u][v] = min(f[u][v], w);
            f[v][u] = min(f[v][u], w);
        }
    //预处理最短路
    for (int k = 1; k <= n; k ++ )
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )  
                f[i][j] = min(f[i][j], f[i][k] + f[k][j]);

    //处理询问
    reverse(vq.begin(), vq.end());
    vector<ll> ans;
    for (int i = 0; i < vq.size(); i ++ )
        if (get<0>(vq[i]) == 1){ //加边
            int id = get<1>(vq[i]);
            auto [u, v, w] = e[id];
            for (int x = 1; x <= n; x ++ )
                for (int y = 1; y <= n; y ++ ){
                    f[x][y] = min(f[x][y], f[x][u] + f[v][y] + w);
                    f[x][y] = min(f[x][y], f[x][v] + f[u][y] + w);
                }
        }else{ //询问
            auto [c, x, y] = vq[i];
            if (f[x][y] < 1e18)
                ans.push_back(f[x][y]);
            else    
                ans.push_back(-1);
        }
    
    reverse(ans.begin(), ans.end());
    for (auto d : ans){
        cout << d << '\n';
    }
}