2019icpc南昌邀请赛H. Another Sequence

本文分享了一种使用快速沃尔什-哈达玛变换(FWT)的算法模板,并结合set数据结构进行区间查询和更新操作的高效解决方案。通过维护数组中相同元素段的信息,利用set的二分查找特性,实现对连续区间的快速修改与查询,避免了复杂度的退化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接
思路:先贴一个fwt模板。
由于数组是一些 相同的元素段 组成的。所以用一个set维护一下,每个段的信息。
然后查询直接set上二分。
修改操作是修改一些连续段,把每个段的值都更新一下,为了防止复杂度退化,必须要合并值相同的相邻段。就可以了。剩下的就是set上模拟模拟即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
int N;
void FWT_or(LL *a, int opt){
  for (int i = 1; i < N; i <<= 1)
    for (int p = i << 1, j = 0; j < N; j += p)
      for (int k = 0; k < i; ++k)
        if (opt == 1)a[i + j + k] = (a[j + k] + a[i + j + k]) ;
        else a[i + j + k] = (a[i + j + k]- a[j + k]);
}
LL a[1<<18],b[1<<18];
int n;
set<pair<LL,pair<LL,int>>>s;
LL l1,l2;
int l3;
vector<pair<LL,pair<LL,int>>>ad,de;
int add(LL x,LL y,int z){
  if(z==l3){
    l1=x;
    return 1;
  }
  if(l3!=-1){
    ad.pb(mp(l1,mp(l2,l3)));
    l3=-1;
  }
  l1=x;l2=y;l3=z;
  return 0;
}
void LA(){
  for(auto k:de){
    s.erase(k);
  }
}
void LB(){
  for(auto k:ad){
    s.insert(k);
  }
}
int main() {
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
    int x;
    scanf("%d",&x);
    a[x]++;
  }
  for(int i=1;i<=n;i++){
    int x;
    scanf("%d",&x);
    b[x]++;
  }
  int l=0;
  while((1<<l)<100000)l++;
  n=N=1<<l;
  FWT_or(a,1);
  FWT_or(b,1);
  for(int i=1;i<n;i++)a[i]*=b[i];
  FWT_or(a,-1);
  LL tot=0;
  for(int i=1;i<n;i++){
    if(a[i]){
      s.insert(mp(tot+a[i],mp(tot,i)));
    }
    tot+=a[i];
  }
  int m;scanf("%d",&m);
  for(int i=1;i<=m;i++){
    LL l,r;
    scanf("%lld%lld",&l,&r);
    if(!l){
      auto g=s.lower_bound(mp(r,mp(0,0)));
      printf("%d\n",(*g).se.se);
    }else{
      ad.clear();de.clear();
      auto g=s.lower_bound(mp(l,mp(0, 0)));
      l3=-1;l2=0,l1=0;
      pair<LL,pair<LL,int>>x=*g;
      if(l-1-x.se.fi>0){
        add(l-1,x.se.fi,x.se.se);
        add(min(r,x.fi),l,sqrt(x.se.se));
        if(r<x.fi){
          add(x.fi,r,x.se.se);
        }
      }else {
        add(min(r,x.fi),x.se.fi,sqrt(x.se.se));
        if(r<x.fi){
          add(x.fi,r,x.se.se);
        }
      }
      de.pb(x);
      ++g;
      while(g!=s.end() &&(*g).fi<=r){
        add(((*g).fi),(*g).se.fi,sqrt((*g).se.se));
        de.pb(*g);
        g++;
      }
      if(g!=s.end()){
        if((*g).se.fi<r){
          add(r,(*g).se.fi,sqrt((*g).se.se));
          add((*g).fi ,r ,(*g).se.se);
          de.pb(*g);
        }
      }
      if(l3!=-1){
        ad.pb(mp(l1,mp(l2,l3)));
      }
      LA();
      LB();
    }
  }
  return 0;
}
// 6 10 11 20 6 20 21 25
<think>嗯,用户想要找2024年ICPC昆明邀请赛的题目解析,但根据提供的引用内容,现有的资料只覆盖到2022年昆明的题目,比如引用[1]提到2020、2021年的ICPC和CCPC题目,以及引用[4]详细解析了2022昆明站的G题。不过用户询问的是2024年的,这可能还没有公开的解析,或者可能还没有举办。需要先确认是否存在2024年的比赛信息,或者是否用户可能记错了年份?比如,2024年的比赛可能尚未举行,或者相关信息还未被整理发布。 首先,检查提供的引用内容,发现最新的昆明站信息是2022年的,引用[4]讨论的是2022昆明G题。用户提到的2024年可能是个错误,或者他们希望提前获取信息。但通常比赛结束后才会有解析,所以需要告知用户目前没有相关资料,并建议他们关注官方渠道或后续的社区分享。同时,可以推荐现有的2022年昆明题解作为参考,帮助用户了解题型和考点,比如动态规划、期望计算等常见问题。 另外,用户可能对如何准备比赛感兴趣,可以建议他们分析历年题目类型,比如引用[1]提到的区域赛常考题型,或者引用[3]中提到的训练经验。需要确保回答准确,避免提供不存在的资源,同时提供有用的替代信息,帮助用户找到最近的可用资料。</think>关于2024年ICPC昆明邀请赛题目解析,目前尚未有官方或主流平台发布完整的题目解析报告。根据历史信息推测,ICPC区域赛的题目解析通常会在赛后由参赛队伍、算法社区或教练团队逐步整理发布。以下是可参考的备赛建议和现有资源: --- ### 一、近期ICPC题型趋势参考 1. **动态规划与组合数学** 如2022年昆明站G题考察了**概率期望与递推关系**,需掌握马尔可夫链、状态转移方程的建立[^4] $$E = \sum_{i=1}^n \left( \frac{p_i}{1-p_i} \cdot \sum_{j \neq i} \frac{p_j}{1-p_i} \right)$$ 此类问题常需分析极限状态下的数学期望。 2. **数据结构优化** 近年区域赛常出现需要**线段树/树状数组维护区间性质**的题目,例如区间最值、历史版本查询等。 3. **图论与网络流** 包括最小割建模、分层图最短路等高级技巧,如2021年沈阳站曾出现网络流与二分答案结合的题目[^2]。 --- ### 二、获取解析的途径建议 1. **官方渠道** 关注ICPC官网及昆明站承办院校的赛事公告,解析可能通过**赛后题解报告会**发布。 2. **算法社区** - **Codeforces**:搜索标签`[ICPC Kunming 2024]` - **知乎/掘金**:技术博主常撰写详细题解(例:2022年G题推导过程) 3. **训练平台** 尝试在**Codeforces Gym**或**牛客竞赛**题库中查找昆明站模拟赛题。 --- ### 三、历届昆明站真题参考 若需练习类似题型,可参考2022年昆明站题目: - **G题(豆子操作期望)**:结合概率论与递推,需推导稳定状态下的位置关系 - **B题(几何构造)**:通过坐标系变换简化多边形切割问题 ```python # 示例:概率期望计算的代码框架 def calculate_expected_value(probabilities): n = len(probabilities) expected = 0.0 for i in range(n): pi = probabilities[i] term = pi / (1 - pi) if pi != 1 else 0 sum_other = sum(pj / (1 - pi) for j, pj in enumerate(probabilities) if j != i) expected += term * sum_other return expected ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值