2019 ICPC EC-Final

reproducen 2019 CIPC CE-Final


Una ciudad

Significado de las preguntas:

Para n m, n * m representa una rejilla
de conexión opcionalmente puntos en la cuadrícula, si el punto medio de esta línea son los puntos de la red tienen la intención de cumplir con el problema.
Pregunta cómo muchos de tales líneas (es decir, en el punto final de la red, los puntos de rejilla son punto medio, la longitud de la línea no es 0)
Rango de datos: n, m <= 1E3

ideas:

Enumeración posición al punto medio.

código:

#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
    int n,m;
    cin>>n>>m;
    n++,m++;
    int ans=0;
    for(int i=1;i<=n;i++){//枚举中点
        for(int j=1;j<=m;j++){
            int a=min(i,n-i+1);
            int b=min(j,m-j+1);
            ans+=(a-1)*(b-1)*2+(a-1)+(b-1);
        }
    }
    cout<<ans<<endl;
    return 0;
}

C.Dirichlet k-ésima raíz (

problema de convolución, hasta gratis


E.Flow

Significado de las preguntas:

Dado n M nodos bordes grafo no dirigido ponderados. En donde n tiene un extremo de inicio a un número de caminos independientes, la ruta y el mismo número de nodos (la misma longitud de la trayectoria). Cada lado tiene el lado derecho.
Una operación puede hacer que el borde derecho de uno de los lados más uno, menos uno otro lado derecho. Q hace que el punto de partida hasta el final de la operación máximo flujo total requiere un número mínimo de veces.
Rango de datos: n <= 1e5, m < = 2E5, el peso borde <= 1e9

ideas:

Debido a que la longitud de la trayectoria es la misma. Supongamos que todos los pesos se acumulan a los bordes en una cadena, que puede ser introducido y el derecho de flujo máxima lado = / (longitud de cadena), el último de los cuales es el flujo máximo.
El lado derecho de cada cadena están ordenadas, y luego en capas, se calcula cada capa, y el lado derecho.
Debido a que para obtener el máximo flujo, por lo que el lado derecho de cada capa y el flujo máximo debe ser mayor que o igual, menor que el máximo flujo hasta su finalización, de modo que podemos calcular el número de operaciones.

código:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
int head[maxm],nt[maxm<<2],to[maxm<<2],w[maxm<<2],tot;
vector<int>temp;
int flow[maxm];
int n,m;
void add(int x,int y,int z){
    tot++;nt[tot]=head[x];head[x]=tot;to[tot]=y;w[tot]=z;
}
void dfs(int x,int fa){
    if(x==n)return ;
    for(int i=head[x];i;i=nt[i]){
        int v=to[i];
        if(v==fa)continue;
        temp.push_back(w[i]);
        dfs(v,x);
    }
}
signed main(){
    cin>>n>>m;
    int sum=0;
    for(int i=1;i<=m;i++){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c);
        add(b,a,c);
        sum+=c;
    }
    int elen=0;//路径长度
    for(int i=head[1];i;i=nt[i]){
        temp.clear();
        temp.push_back(w[i]);
        dfs(to[i],1);
        sort(temp.begin(),temp.end());//排序
        if(!elen)elen=temp.size();
        for(int i=0;i<elen;i++){//分层求和
            flow[i+1]+=temp[i];
        }
    }
    int maxflow=sum/elen;
    int ans=0;
    for(int i=1;i<=elen;i++){
        if(flow[i]<maxflow){
            ans+=maxflow-flow[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

H.King

Significado de las preguntas:

Para una longitud de la matriz y un número primo p n es
la definición de, satisface secuencia s una secuencia s de rey: s (i-1) * q% p = s (i), ( series geométricas en sentido die)
ahora de un sintonice una secuencia, la secuencia es un rey secuencia, Q es la longitud máxima del número, si la longitud máxima es inferior a N / 2 -1 salidas.
Rango de datos: n <= 2E5, p < = 1e9 + 7, para asegurar que p es un número primo

ideas:

El punto clave de este problema es que el n / 2, (de hecho someter cada condición no puede ser ignorado!)
Debido a que la longitud de al menos n / 2, por lo que los números de secuencia debe tener al menos dos adyacentes o separados por 1, de modo que la razón común se tendrá ciertamente un adyacentes o separados
por mapa todos capaces de Parada (i-1) a una (i) y a (i-2) a una (i) de la relación común de que el número de
ocurrencias de una relación determinada q aparentemente común será mayor que o igual a un número

número de registro de entrada es mayor que n / 8, de lo que parece tomar max (n / 6 también, para empujar mucho tiempo no saben cómo el número)

código:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxm=2e5+5;
unordered_map<int,int>mark;
int inv[maxm];
int a[maxm];
int n,p;
int ppow(int a,int b,int mod){
    int ans=1%mod;
    while(b){
        if(b&1)ans=(ll)ans*a%mod;
        a=(ll)a*a%mod;
        b>>=1;
    }
    return ans;
}
int cal(int q){
    unordered_map<int,int>dp;
    int ans=0;
    for(int i=n;i>=1;i--){
        dp[a[i]]=dp[(ll)a[i]*q%p]+1;
        ans=max(ans,dp[a[i]]);
    }
    return ans;
}
signed main(){
    int T;
    cin>>T;
    while(T--){
        unordered_map<int,int>t;
        mark=t;
        scanf("%d%d",&n,&p);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            inv[i]=ppow(a[i],p-2,p);
        }
        for(int i=2;i<=n;i++){
            int q=(ll)a[i]*inv[i-1]%p;
            mark[q]++;
        }
        for(int i=3;i<=n;i++){
            int q=(ll)a[i]*inv[i-2]%p;
            mark[q]++;
        }
        int ans=0;
        for(auto i:mark){
            if(i.second>=n/8){
                ans=max(ans,cal(i.first));
            }
        }
        if(ans*2<n)ans=-1;
        printf("%d\n",ans);
    }
    return 0;
}

M.Value

Significado de las preguntas:

De longitud N para las matrices A y B
para cada ubicación i, es opcional Alternativamente, si el he seleccionado, entonces la puntuación total sería añadir un (i).
Si selecciona i y j, y i, j> = 2, y i k = J (k> = 2), entonces se necesita restar b (j), y más si i cumplen esta condición, b (j) se se sustrae varias veces.
Ahora usted quiere encontrar una opción que la salida máxima puntuación total final de esta puntuación máxima.
Rango de datos: n <= 1e5,1 <= a (i), b (i) <= 1e9

ideas:

un (1) obligatoria, ya que no afecta a otros números.
Fácil de ver diferentes base del logaritmo no influir entre sí, por ejemplo, 8 y 9 no afectan entre sí porque 8 = 2 . 3 , 9 = 3 2 ,
encontró que sólo n 1e5,2 . 17 es mayor que 1E5, así que si el paquete por número base, el grupo más grande es la base para el grupo 2, el número no es más de 17, un número de otros grupos más pequeños.
Es posible presionar la base de paquetes, y para cada conjunto de opciones binarias enumeró tener como máximo, la acumulación es la respuesta.

código:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
vector<int>g[maxm];
int cnt=0;
int mark[maxm];
int a[maxm];
int b[maxm];
int solve(int x){//计算第x组的最大答案
    int len=g[x].size();
    int ans=0;
    for(int i=0;i<(1<<len);i++){
        for(int j=0;j<len;j++)mark[g[x][j]]=0;//清空标记
        int temp=0;
        for(int j=0;j<len;j++){
            if(i>>j&1){
                temp+=a[g[x][j]];
                temp-=mark[g[x][j]]*b[g[x][j]];
                for(int k=g[x][j]*g[x][j];k<=g[x][len-1];k*=g[x][j]){
                    mark[k]++;
                }
            }
        }
        ans=max(ans,temp);
    }
    return ans;
}
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)cin>>b[i];
    for(int i=2;i<=n;i++){//按底数分组
        if(mark[i])continue;
        cnt++;
        for(int j=i;j<=n;j*=i){
            mark[j]=1;
            g[cnt].push_back(j);
        }
    }
    int ans=a[1];//a[1]必选,因为对后续无影响
    for(int i=1;i<=cnt;i++){//对每一组二进制枚举
        ans+=solve(i);
    }
    cout<<ans<<endl;
    return 0;
}

Publicados 430 artículos originales · ganado elogios 36 · Vistas a 20000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_44178736/article/details/104741866
Recomendado
Clasificación