Pagini recente » Cod sursa (job #1008366) | Cod sursa (job #23940) | Cod sursa (job #2757078) | Cod sursa (job #267436) | Cod sursa (job #922372)
Cod sursa(job #922372)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("oite.in");
ofstream g("oite.out");
#define nmax 1024
#define Lmax 1000005
#define MOD 666013
int n, L, a[nmax];
typedef vector< pair<int,int> >::iterator it;
vector< pair<int,int> > lista[MOD+4];
int dp[3][5][Lmax];
void citeste(){
f >> n >> L;
for(int i=1; i<=n; ++i) f >> a[i];
}
void baga(int val, int poz){
int rest = val % MOD;
lista[rest].push_back( make_pair( val, poz) );
}
void bagaHash(){
for(int i=1; i<=n; ++i){
for(int j=i+1; j<=n; ++j){
baga(a[i]+a[j], i);
}
}
}
inline int cauta(int Val, int poz){
if (Val > L) return 0;
int rest = Val % MOD;
int cnt = 0;
for(it i=lista[rest].begin(); i!=lista[rest].end(); i++){
if( (*i).first == Val && (*i).second > poz ){
++cnt;
}
}
return cnt;
}
void init(int linie){
for(int j=1; j<=4; ++j){
for(int k=0; k<=L; ++k) dp[linie][j][k] = 0;
}
}
void bagaDinamica(){
// dp[i][j][L] = nr de siruri cu suma L ce se termina sau nu se termina pe i si are j termeni
int linie = 1;
dp[1-linie][1][ a[1] ] = 1;
for(int i=2; i<=n; ++i){
init(linie);
for(int j=1; j<=4; ++j){
for(int k=0; k<=L; ++k){
dp[linie][j][k] += dp[1^linie][j][k];
if ( j < 4 ) {
int newK = k + a[i];
if (newK > L) continue;
dp[linie][j+1][newK] += dp[1^linie][j][k];
}
}
}
linie = 1^ linie;
}
g << dp[1^linie][4][L] << "\n";
}
void rezolva(){
// bag fiecare pereche i, j i<j intr-un hash; apoi vin cu fiecare pereche si caut suma
// in hash
if (L <= 1000000){
bagaDinamica();
return;
}
bagaHash();
int rez =0;
for(int i=1; i<=n; ++i){
for(int j=i+1; j<=n; ++j){
rez += cauta(L - (a[i] + a[j]), j );
}
}
cout << rez << "\n";
g << rez << "\n";
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}