1. 程式人生 > >hdu5213(莫隊演算法+容斥定理)

hdu5213(莫隊演算法+容斥定理)

題意:給我們n個數,然後給我們一個數字K,再給我們兩個區間[L,R],[U,V],問我們從這兩個區間裡分別取一個數,有多少種取法,可以使得所取的兩個數和為K。

分析:莫隊演算法+容斥定理。因為莫隊演算法是知道[l,r]的值後可以求[l’,r’]的值,因為每次都會給兩個區間,所以我們需要將兩個不相關的區間想辦法讓他們產生連續。對於[x1,y1][x2,y2]我們這時候可以通過容斥定理將其變為F[x1,y1,x2,y2]=F[x1,y2]+F[y1+1,x2-1]-F[y1+1,y2]-F[x1,x2-1]將一次求解變成4個區間分別求解,每次在一個區間中求解有多少種取法可以使得兩個數和為k。

AC程式碼如下:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <queue>
#include <map>
#include <vector>

using namespace std;

const int maxn = 30000+10;

int N,K,a[maxn],m,belong[maxn],ans;
int
sum[2*maxn]; struct Query { int x1,y1,x2,y2,ans; }q[maxn];///儲存查詢 struct Query1 { int l,r,ans,flag,fa; }arr[maxn*4];///儲存區間 bool cmp1(Query1 a, Query1 b)///分塊排序 { if(belong[a.l]==belong[b.l]) return a.r<b.r; return belong[a.l]<belong[b.l]; } void updata(int pos, int flag) { sum[a[pos]]+=flag; if
(K>a[pos]) ans+=sum[K-a[pos]]*flag; } int main() { while(scanf("%d",&N)!=EOF) { scanf("%d",&K); for(int i=1; i<=N; i++) scanf("%d",&a[i]); int block =sqrt(N); for(int i=1; i<=N; i++) belong[i]=(i-1)/block+1; scanf("%d",&m); for(int i=1; i<=m; i++) { scanf("%d %d %d %d",&q[i].x1,&q[i].y1,&q[i].x2,&q[i].y2); q[i].ans=0; for(int j=0; j<4; j++) { arr[i+j*m].fa=i; arr[i+j*m].ans=0; }///初始化各區間 arr[i].flag=1,arr[i].l=q[i].x1,arr[i].r=q[i].y2;///[x1,y2]; arr[i+m].flag=1,arr[i+m].l=q[i].y1+1,arr[i+m].r=q[i].x2-1;///[y1+1,x2-1] arr[i+m*2].flag=0,arr[i+m*2].l=q[i].y1+1,arr[i+m*2].r=q[i].y2;///[y1+1,y2] arr[i+m*3].flag=0,arr[i+m*3].l=q[i].x1,arr[i+m*3].r=q[i].x2-1;///[x1,x2-1] } sort(arr+1,arr+4*m+1,cmp1); ans=0; int l=1,r=0; memset(sum,0,sizeof(sum)); sum[a[1]]=1; for(int i=1; i<=4*m; i++) { while(l<arr[i].l) { updata(l,-1); l++; } while(l>arr[i].l) { l--; updata(l,1); } while(r<arr[i].r) { r++; updata(r,1); } while(r>arr[i].r) { updata(r,-1); r--; } arr[i].ans=ans; } for(int i=1; i<=4*m; i++) { int x=arr[i].fa; int y=arr[i].ans; if(arr[i].flag) q[x].ans+=y; else q[x].ans-=y; } for(int i=1; i<=m; i++) printf("%d\n",q[i].ans); } return 0; }

相關推薦

hdu5213演算法+定理

題意:給我們n個數,然後給我們一個數字K,再給我們兩個區間[L,R],[U,V],問我們從這兩個區間裡分別取一個數,有多少種取法,可以使得所取的兩個數和為K。 分析:莫隊演算法+容斥定理。因為莫隊演算法是知道[l,r]的值後可以求[l’,r’]的值,因

hdu_5213_Lucky(演算法+定理)

題意:給你n個數,一個K,m個詢問,每個詢問有l1,r1,l2,r2兩個區間,讓你選取兩個數x,y,x,y的位置為xi,yi,滿足l1<=xi<=r1,l2<=y2<=r2,使得x+y=K; 題解:首先,這題沒有修改操作,即可以離線,離線區間問題就

HDU5213 BestCoder Round 39D】【演算法+】Lucky 兩個區間各選一個數使得和為K的方案數

#include<stdio.h> #include<string.h> #include<ctype.h> #include<math.h> #include<iostream> #include<stri

TrickGCD比烏斯反演+定理

連結:http://acm.hdu.edu.cn/showproblem.php?pid=6053 hdu6053 TrickGCD 題目解析: 令sum[k]為k能夠出現的個數 eg: Input 3 6 6 9 各個數字出現的情況 1 1 1 2 2 2 3 3

HDU 1695 GCD定理

font hint cup show lan orm required stdio.h test case GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/

【ZOJ - 2836】【Number Puzzle】定理

題目: Given a list of integers (A1, A2, ..., An), and a positive integer M, please find the number of positive integers that are not greater than M

Newcoder 39 F.重排的迴文串演算法+位運算

Description 給一個長為 n n n 的只含小寫字母的字串 每次查詢一個區間$ [l

Newcoder 58 F.序列查詢演算法+分塊+連結串列

Description 給你一個序列 a a a,有

5768中國剩餘定理+定理

題意: 小明認為能被7整除的數能給他帶來好運,但是如果這些數存在x%pi=ai(1<=i<=n)的話,它反而會給小明帶來壞運。 問[x,y]區間裡有多少個數能給小明帶來好運? 分析: 明顯的容斥題,但在容斥過程中得算x%pi=ai(1<=i<=

hdu 4135 Co-prime分解質因數+定理

【題目】 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8210    

P1494 [國家集訓隊]小Z的襪子演算法

莫隊板子 程式碼 #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #define int long long using namespace std; st

2018年山東省第九屆acm省賽 F題 Four-tuples離散數學 定理

Four-tuplesTime Limit: 2000 ms Memory Limit: 524288 KiBProblem DescriptionGiven l1, r1, l2, r2, l3, r3, l4, r4, please count the number of

hdu 2197 本原串定理

本原串 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 547    Accepted Submission

hdu 1695 GCD定理

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4308    Accepted Submissio

CSU 1515: Sequence演算法

Description Give you a sequence consisted of n numbers. You are required to answer how many pairs

CSU 1515 Sequence演算法

Description 給出一個長度為n的序列ai,進行m次查詢,每次查詢區間[l,r]中滿足|ai-aj|=1的(i,j)對數(l<=i < j<=r) Input 第一行為兩

poj1091跳蚤定理

一個 frame 結果 i++ 其中 cout type n+1 include 題目:Z城市居住著很多只跳蚤。在Z城市周六生活頻道有一個娛樂節目。一只跳蚤將被請上一個高空鋼絲的正中央。鋼絲很長,可以看作是無限長。節目主持人會給該跳蚤發一張卡片。卡片上寫有N+1個自然數。其

BZOJ 3289 Mato的文件管理+樹狀數組

light limit .com print long long blank cmp tar getch 【題目鏈接】 http://www.lydsy.com/JudgeOnline/problem.php?id=3289 【題目大意】   求靜態區間逆序

Problem B. Harvest of Apples 組合數求和沒怎麼看懂

Problem B. Harvest of Apples Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submiss

【BZOJ 4818】 4818: [Sdoi2017]序列計數 矩陣乘法、計數

【分析】   f[i][j]表示填i個數,mod為j的方案數。   這個轉移可以用矩陣加速啦,那麼n很大也沒關係了。   然後要至少有一個質數,就用總方案數-沒有一個質數。   然後一開始跑20s,看到別人2s,然後覺得這個迴圈矩陣的矩陣乘法可以O(n^2),改了就2s了。。 1 #include